Laden...

Noch einmal Regex

Erstellt von Der Tim vor 17 Jahren Letzter Beitrag vor 17 Jahren 4.777 Views
D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren
Noch einmal Regex

Hallo,

ich hatte schon vor einiger Zeit mich einmal nach dem Regex optionen erkundigt. Nun ist mir etwas aufgefallen was ich so nicht erwartet hätte:

string doof = "Tim ist zu doof einen Text zu lesen.";
Console.Out.WriteLine(doof);
string modify = Regex.Replace(doof, @"ist \w einen Text zu", "ist fertig mit");
Console.Out.WriteLine(modify);
Console.ReadLine();

Kann mir jemand sagen wieso der Text nicht ersetzt wird?
Ich habe auch schon alle möglichen Optionen bei den RegexOptions ausprobiert.

Bin über jede Antwort dankbar.

TIM 🙂

S
129 Beiträge seit 2006
vor 17 Jahren

Ich weiß nicht was bei dir rauskommen soll. Der Satz würde danach irgendwie keinen Sinn machen.


string doof = "Tim ist zu doof einen Text zu lesen.";
string modify = Regex.Replace(doof, @"ist zu doof einen Text zu", "ist fertig mit");

doof = Tim ist zu doof einen Text zu lesen.
modify = Tim ist fertig mit lesen.

//// scarp

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

Hallo,

ich bekomme zwei mal den Satz

"Tim ist zu doof einen Text zu lesen."

Ich erwarte aber einmal:

"Tim ist zu doof einen Text zu lesen." und
"Tim ist fertig mit lesen"

TIM 🙂

T
243 Beiträge seit 2006
vor 17 Jahren

Da brauchst Du gar keinen Regex:

string doof = "Tim ist zu doof einen Text zu lesen.";
string modify = doof.Replace("zu doof einen Text zu", "fertig mit");
S
129 Beiträge seit 2006
vor 17 Jahren

Ja in meinem Beispiel funktioniert es.

Deine Reg-Pattern sind schlichtweg und ergreifend: falsch.

//// scarp

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

Hi scarp,

kannst du mir auf vielleicht sagen was "schlicht und ergreifend" flasch ist?

\w -> http://msdn2.microsoft.com/de-de/library/20bw873z.aspx

Bevor du schreibst ich muss zwei \w nehmen weil da Wortzeichen steht, ich hab das auch schon ausprobiert 😉

TIM 🙂

S
129 Beiträge seit 2006
vor 17 Jahren

Original von typhos
Da brauchst Du gar keinen Regex:

string doof = "Tim ist zu doof einen Text zu lesen.";  
string modify = doof.Replace("zu doof einen Text zu", "fertig mit");  

Stimmt^^.

@Tim: Du willst also:

"Tim ist zu doof einen Text zu lesen."
"Tim ist fertig mit lesen"

Generell willst du also alle Wörter zwischen "ist" und "einen" mit "ist fertig mit" ersetzen?

//// scarp

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

So wie ich dich verstehe ja.

Mein Ziel ist es später in meinen HTML Dateien wie folgt zu arbeiten.
Angabe anfang und end Tag und alles dazwischen und auch den Tag selber löschen.

Oder bsp.

....<a>...</a></b> durch
<a>...</a><a>...</a></b> ersten möchte. Natürlich weiß ich nicht was in ... steht. Deswegen \w.

Versteht ihr nun wieso ich \ nutzen möchte?

TIM 🙂

L
497 Beiträge seit 2006
vor 17 Jahren

Wenn Du in html-Tags etwas ersetzen willst, warum machst Du das dann auf Wortbasis? Da wäre doch .* oder eher .*? viel besser...

Sarkusmus ist, wenn nichts mehr hilft, außer Lachen.

T
512 Beiträge seit 2006
vor 17 Jahren

Du hast einfach nur hinter dem \w das + vergessen, sonst wird er nur einen Buchstaben erwarten.

PS für HTML Tags sind Regex nicht sonderlich gut geeignet, weil HTML keine Reguläre Sprache ist. Beispiel:

<a>1<b>2</b>3</a>4<a>5</a>

Mit dem Ausdruck "<a>\w+</a>" würdest du nur erhalten: "<a>5</a>", weil ja nicht auf verschachtelte Tags gematcht wird.

Mit dem Ausdruck "<a>.*</a>" würdest du erhalten: "<a>1<b>2</b>3</a>4<a>5</a>", weil er so viel wie möglich reinstopfen will.

Kurzum: Das funktioniert nur vernünftig wenn du keine inneren Tags erwartest.

PPS die Ausdrücke dienen nur der Veranschaulichung, es müssten bestimmt noch ein paar \ eingefügt werden damits funktioniert, nur wirds dadurch auch etwas unverständlicher als Beispiel.

e.f.q.

Aus Falschem folgt Beliebiges

T
243 Beiträge seit 2006
vor 17 Jahren

Genau. Und dann müsste es zweimal eingesetzt werden:

\w+ \w+

Du möchtest ja "zu" und "doof" ersetzen.

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

Hi typhos,

kannst du mir auch sagen was ich mache, wenn ich nicht weiß wie viele Wörter ich habe?

TIM 🙂

T
243 Beiträge seit 2006
vor 17 Jahren

Hmm, habs nicht getestet, aber so müsste es gehen:

(\w+(\W+|$))*

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo typhos, hallo zusammen,

Hmm, habs nicht getestet

dafür gibt es ja den On-the-fly Regex-Tester: Regex-Lab

herbivore

T
243 Beiträge seit 2006
vor 17 Jahren

Ja, hab mir das Tool auch schon geladen (Danke dafür, ist wirklich sehr gut!!), aber gestern hatte ich es nicht zur Hand und war zu faul, es nochmal zu laden X(

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo typhos,

danke für das Lob. Mein Hinweis war auch nicht als Kritik gemeint, sondern als nützlicher Tipp. Für dich und andere.

herbivore

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

Guten Morgen,

auch von mir ein großes Lob an herbivore. Das Programm ist echt cool 🙂

Tyhos, wie bist du auf die Sache mit dem "(\w+(\W+|$))*" gekommen?
Leider klappt es noch nicht so ganz wie es soll.
Suche noch die Bedeutung von $.

TIM 🙂

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Der Tim,

Suche noch die Bedeutung von $.

die steht in der sehr guten SDK-/MSDN-Doku. Ohne die wirst du mit deinen Pattern nicht weit kommen. 🙂

$ steht für das Zeilen- oder für das String-Ende je nach RegexOptions.Multiline

herbivore

64 Beiträge seit 2005
vor 17 Jahren

Hi Tim... was mir bei Regex sehr weitergeholfen hat ist das hier....

MfG Pat

T
243 Beiträge seit 2006
vor 17 Jahren

\w+ bedeutet irgendein Wort mit mindestens einem Zeichen
\W+ bedeutet mindestens ein Zeichen, welches in keinem Wort vorkommt (also Sonderzeichen, Leerezciehn usw.)
$ bedeutet das Ende des Strings

Der ausdruck sollte also bedeuten

WORT gefolgt von mindestens einem SONDERZEICHEN/LEERZEICHEN oder ENDE_DES_STRINGS
das Ganze dann beliebig oft

Hab es gerade mal mit herbivore's Tool getestet:

String: Tim ist zu doof einen Text zu lesen
Pattern: Tim (\w+\W+|$)*Text zu lesen

Ergebnis:
ist, zu, doof, einen

D
Der Tim Themenstarter:in
130 Beiträge seit 2005
vor 17 Jahren

Hi,

kann mir jemand sagen ob das Programm bzw. Regex Zeichenbegrenzt ist?

Hab hab grade einen Text mehr recht vielen Zeichen nur mit Zeichen a-z und A-Z. Bei dem Pattern .* wird nur bis zu einem bestimmten Punkt ausgegeben?

Leider wird bei Value nur bis zu einer bestimmten Stelle ausgegeben.

Das ganze habe ich auch einmal mit Regex in in der Konsole gemacht. Auch hier wurde aus meinem .* in zwei Texte aufgeteilt.

string doof = "hallo ich bin der tim und schreibe einen sehr sehr langen text das ganze passiert natürlich ohne komma hallo ich bin der tim und schreibe einen sehr sehr langen text das ganze passiert natürlich ohne komma hallo ich bin der tim und schreibe einen sehr sehr langen text das ganze passiert natürlich ohne komma hallo ich bin der tim und schreibe einen sehr sehr langen text das ganze passiert natürlich ohne komma hallo ich bin der tim und schreibe einen sehr sehr langen text das ganze passiert natürlich ohne komma punkt";

Console.Out.WriteLine(doof);
string modify = Regex.Replace(doof, @".*", "b");
Console.Out.WriteLine(modify);

Die Ausgabe ist bb, könnt ihr mir das erklären?
TIM 🙂

PS. @herbivore: Dieses soll keine Kritik oder ähnliches darstellen. Frage nur aus interesse.

T
512 Beiträge seit 2006
vor 17 Jahren

Der letzte Match ist leer, frag mich nicht warum. Also wenn du dir mal die Matches ausgeben lässt, ist der Erste der komplette Text, und der Zweite leer.

Aber wie gesagt, mit .* sollte man vorsichtig sein, weil er alles reinstopft was geht. Er nimmt dann die letzte mögliche Ausfahrt, statt der ersten. Das heißt wenn du nach <a>.*</a> suchst, und es kommt zweimal sowas vor, erhältst du den kompletten Text vom ersten <a> bis zum letzten </a>

e.f.q.

Aus Falschem folgt Beliebiges

T
243 Beiträge seit 2006
vor 17 Jahren

Wenn ich mich nicht irre, kann man diese gefräßige Eigenschaft über einen Parameter oder so abstellen. Dann nimmt er auch die "erste Ausfahrt"...

edit: Habe gerade nochmal nachgesehen: Um das .* nicht-gefräßig zu machen, muss man .*? schreiben.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo Der Tim,

also ich kann mir den Effekt nicht erklären und es mir eigentlich auch nicht vorstellen. 🙂

Hallo typhos,

.*? ist aber für sich genommen das gleiche wie .

herbivore

T
243 Beiträge seit 2006
vor 17 Jahren

Ja, wenn es allein steht, aber bei z.B.

"<a>foo</a>...<a>bar</a>"

bringt "<a>.*</a>" das Ergebnis:

"<a>foo</a>...<a>bar</a>"

und "<a>.*?</a>" bringt hingegen:

"<a>foo</a>"

Und das habe ich ja eigentlich gemeint 😉

edit: Habe eben nochmal kurz getestet. Du hast Unrecht, herbivore:

in der Zeichenkette "abcd" zum Beispiel bringt "." das Eregbnis "a", ".*?" hingegen bringt nichts. Also ist es doch nicht das Gleiche...

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo typhos,

Also ist es doch nicht das Gleiche...

stimmt, .+? wäre das gleiche

herbivore

1
310 Beiträge seit 2006
vor 17 Jahren

Habe ein ähnliches Problem, aber bekomme es nicht gelöst.

In meinem string kommt die Zeichenfolge "<>" ohne " vor.

Mit

 
helpstring = Regex.Replace(helpstring, "<", "");
helpstring = Regex.Replace(helpstring, ">", "");


Bekomme ich die zwar weg, aber nicht mit

 
helpstring = Regex.Replace(helpstring, "<>", "");

Die erste Lösung kann ich nicht nehmen, da sie mir alle Tags löscht. Wie kann ich nur das <>-Tag in meinem String löschen?

T
243 Beiträge seit 2006
vor 17 Jahren

Wenn wirklich nur "<>" vorkommt, brauchst Du keinen Regex. Dann kannst Du das einfach mit:

helpstring = helpstring.Replace("<>", "");

ersetzen.

Wenn aber zwischen "<" und ">" noch irgendetwas kommt, kannst Du das so ersetzen:

helpstring = Regex.Replace(helpstring, "<.*?>", "");

Aber das löscht Dir wieder alle Tags weg...

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo 11.08.2006,

wenn du wirklich nur die spitzen Klammern weg haben willst:

helpstring = helpstring.Replace("[<>]", "");

herbivore

564 Beiträge seit 2005
vor 17 Jahren

Die erste Lösung kann ich nicht nehmen, da sie mir alle Tags löscht. Wie kann ich nur das <>-Tag in meinem String löschen?

Sry 11.08.2006 ich versteh nur Bahnhof.

1
310 Beiträge seit 2006
vor 17 Jahren

Hi,

danke für Eure antworten. Leider verschwinden die <>-tags nicht.

Egal ob ich helpstring = helpstring.Replace("<>", "");
oder helpstring = helpstring.Replace("[<>]", ""); verwende...

Und ja, ich will nur die zwei Klammern entfernen, wenn sie so zusammen stehen. Es geht darum einen String "aufzuräumen" um Speicherplatz zu sparen.

564 Beiträge seit 2005
vor 17 Jahren

String.Replace("<>", ""); ersetzt "Bla bla <> blabla" durch "Bla Bla blabla"

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo 11.08.2006,

wenn du das willst:

Und ja, ich will nur die zwei Klammern entfernen, wenn sie so zusammen stehen.

das heißt also wenn spitze Klammer auf, Leerzeichen und spitze Klammer so hintereinander stehen, dass sie dann durch leer ersetzt werden, dann muss

helpstring = helpstring.Replace("<>", "");

gehen.

herbivore

1
310 Beiträge seit 2006
vor 17 Jahren

Hallo Herbivore,

nein, die Klammern ohne Leerzeichen. Aber egal, ob ich das als <> oder < > formuliere, die Klammern verschwinden nicht...

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo 11.08.2006,

das liegt dann aber nicht an dem Replace.

herbivore

564 Beiträge seit 2005
vor 17 Jahren

Zeig mal deinen Code

1
310 Beiträge seit 2006
vor 17 Jahren

Hier die Ausdrücke die meinen String aufräumen: Bis auf <> funktioniert auch alles


//Throw out some characters to save memory
                        helpstring = Regex.Replace(helpstring, "col", "");
                        helpstring = Regex.Replace(helpstring, "timestamp", "");
                        helpstring = Regex.Replace(helpstring, "decode", "");
                        helpstring = Regex.Replace(helpstring, "str", "");
                        helpstring = Regex.Replace(helpstring, "max", "");
                        helpstring = Regex.Replace(helpstring, "aram", "");
                        helpstring = Regex.Replace(helpstring, "rn", "");
                        helpstring = Regex.Replace(helpstring, "name", "");
                        helpstring = Regex.Replace(helpstring, "para_", "");
                        helpstring = Regex.Replace(helpstring, "value_", "");
                        helpstring = Regex.Replace(helpstring, "null", "");
                        helpstring = Regex.Replace(helpstring, ",", "");
                        helpstring = Regex.Replace(helpstring, " ", "");
                        helpstring = Regex.Replace(helpstring, "", "");
                        helpstring = helpstring.Replace("<>", "");
                        helpstring = Regex.Replace(helpstring, "/", "");

564 Beiträge seit 2005
vor 17 Jahren

string helpstring = "Hallo <> ja";
helpstring = helpstring.Replace("<>", "");
Console.WriteLine(helpstring);
Console.ReadLine();

Das funktioniert.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo 11.08.2006,

ich behaupt mal, dass dann in deinem String keine spitzen Klammern direkt hintereinander folgen.

herbivore

1
310 Beiträge seit 2006
vor 17 Jahren

`Hier ein Stück aus meinem String: <>
≤"V44"><><>
≤"N45"><><>
≤"V45"><><>
≤"N46"><><>
≤"V46"><><>
≤"N47">

564 Beiträge seit 2005
vor 17 Jahren

Erstellt bei mir den Text:

≤"V44">
≤"N45">
≤"V45">
≤"N46">
≤"V46">
≤"N47">

Genau das was du willst.

49.485 Beiträge seit 2005
vor 17 Jahren

Hallo 11.08.2006,

gucks dir im Debugger an. Die spitze Klammern werden rausfliegen. Muss irgend ein anderer Fehler sein.

herbivore