Laden...

Mehrfache Wiederholungen eines Zeichens durch *ein* anderes Zeichen ersetzen

Erstellt von RipperMac vor 14 Jahren Letzter Beitrag vor 14 Jahren 1.073 Views
R
RipperMac Themenstarter:in
12 Beiträge seit 2009
vor 14 Jahren
Mehrfache Wiederholungen eines Zeichens durch *ein* anderes Zeichen ersetzen

Hi Leute,

ich würde gerne eine Anwendung schreiben, die eine Datei einliest (textdatei) und einen bestimmten inhalt ersetzt. Mein Problem ist, das ich zwar mit der Funktion umgehen zu weiß, aber ich ein Problem hab wenn das zu ersetzende Zeichen mehrmals nacheinander steht.

zur verdeutlichung was passieren soll:

bsp Textdatei beinhaltet:
jjjjAjjjAjAj
jjjjAjjjjj
jjjA
jjjjjAj
jjAjjjAjjjjjjj
j

dann soll das Program alle j mit beispielsweise einem k ersetzen. Soweit so gut, die Ausgabe wäre in dem Fall:

kkkkAkkkAkAk
kkkkAkkkkk
kkkA
kkkkkAk
kkAkkkAkkkkkkk
k
nun will ich es aber schaffen, dass das ganze pro mehrere j nur ein k ausgibt. Sprich folgende ausgabe soll erreicht werden:

kAkAkAk
kAk
kA
kAk
kAkAk
k

so und hier verzweifel ich...

297 Beiträge seit 2008
vor 14 Jahren

Guten Morgen,

mir fallen spontan ein paar Lösungen ein, die teilweise auch sehr unschön sind, aber dennoch funktionieren sollten.

  1. Im ersten Schritt ersetzt du das j durch das k. Im zweiten ersetzt du kk durch k. Das machst du so lange, bis sich der string nicht mehr ändert.

  2. Mit regulären Ausdrücken und Gruppen baust du dir einen neuen String zusammen.

  3. Du durchläufst den string und schreibst das erste gelesene Zeichen. Wenn das folgende Zeichen das selbe ist, wie das vorherige, gehst du einen Schritt weiter. Wenn es ein anderes ist schreibst du dieses hin und gehst wieder weiter.

Gibt sicherlich noch mehr Möglichkeiten, aber diese sind mir spontan eingefallen.

Viel Spaß beim Umsetzen !

There are 10 kind of people, those who understand binary and those who don't.

Gelöschter Account
vor 14 Jahren

das kannst du in wenigen zeilen mit regex vollbringen.

siehe hierzu: [Artikel] Regex-Tutorial

und auch sehr sehr hilfreich:
On-the-fly Regex-Tester: Regex-Lab

3.825 Beiträge seit 2006
vor 14 Jahren

Hallo RipperMac,

die optimale Lösung hängt auch sehr von der Größe der Textdatei ab.

String-Operation verbrauchen viel Speicher und Zeit.

Bei sehr großen Dateien besser StringBuilder benutzen.

Grüße Bernd

Workshop : Datenbanken mit ADO.NET
Xamarin Mobile App : Finderwille Einsatz App
Unternehmenssoftware : Quasar-3

R
RipperMac Themenstarter:in
12 Beiträge seit 2009
vor 14 Jahren

Also danke für die Antworten, ich hab es jetzt so gelöst:

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;

namespace Replace
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "Dieser Text soll      verarbeitet   werden.    ";
            StreamWriter write = new StreamWriter("Neu Textdokument.txt");

            try
            {
                text = text.Replace(" ", ";");
                while(text.Contains(";;"))
                {
                    text = text.Replace(";;", ";");
                }
                write.WriteLine(text);
            }
            catch 
            {
                write.WriteLine("Der Text konnte nicht verarbeitet werden");
            }

            write.Close();
        }
    }
}

Gruß

Gelöschter Account
vor 14 Jahren

ja, man kann das so lösen, nur ist das so ziemlich der unperfomanteste weg, den man hierbei gehen kann.

916 Beiträge seit 2008
vor 14 Jahren

Hallo RipperMac,

das seh ich auch so wie JAck30lena. Ein deutlich besserer weg ist das mit Regex zu lösen. Ich helf dir mal ein bisschen auf die Sprünge.

(?<!k)k{1,} Dieser regex Ausdruck findet alle k's die aufeinanderfolgen ohne das ein k folgt. Daher genau das was du willst. Man nennt das negativer Lookbehind,

sdfksdfksdfkksdfkkkksdfk

Und am Regex Object gibt es eine Replace Methode, die kannst du dir ja mal anschauen 😉

Again what learned...

390 Beiträge seit 2008
vor 14 Jahren

Hallo RipperMac,
(?<!k)k{1,} Dieser regex Ausdruck findet alle k's die aufeinanderfolgen ohne das ein k folgt.

Hallo rollerfreak2

IMO braucht es keinen Lookahead um alle Ks zu finden. k+ bzw. j+ dürfte reichen.

Gruss

using Skill

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo edsplash,

IMO braucht es keinen Lookahead um alle Ks zu finden. k+ [...] dürfte reichen.

vollkommen korrekt.

herbivore

916 Beiträge seit 2008
vor 14 Jahren

Das ist allerdings wahr das der Lookahead überflüssig ist, aber jetzt weiß RipperMac gleich was ein negativer Lookahead ist... 😃

Again what learned...

R
RipperMac Themenstarter:in
12 Beiträge seit 2009
vor 14 Jahren

Danke für die Antwort, werd mich dem mal annehmen. 😃

Gruß

R
RipperMac Themenstarter:in
12 Beiträge seit 2009
vor 14 Jahren

Hi, also Regex war ein gutes Stichwort. Ich hab es jetzt noch wieder etwas anders gelöst. Sollte eine bessere Lösung sein, oder?

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;

namespace Replace
{
    class Program
    {
        static void Main(string[] args)
        {
            string text = "Dieser Text soll      verarbeitet   werden.    ";
            StreamWriter write = new StreamWriter("Neu Textdokument.txt");

            try
            {
                text = Regex.Replace(text, " +", ";");
                Console.WriteLine(text);
            }
            catch
            {
                Console.WriteLine("Der Text konnte nicht verarbeitet werden");
            }

            write.Close();
            Console.ReadLine();
        }
    }
}

Gruß

49.485 Beiträge seit 2005
vor 14 Jahren

Hallo RipperMac,

wüsste nicht, warum du da eine Exception bekommen solltest. Entweder der Pattern passt oder er tut es nicht. Aber eine Exception gibt es in keinem der beiden Fälle. Die gäbe es nur, wenn der Pattern syntaktisch falsch wäre, aber das ist ja nicht so.

Davon abgesehen würde ich wohl File.ReadAllText oder ReadAllLines verwenden, es sei denn die Dateien können viel größer als der Hauptspeicher werden.

herbivore