Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Text über Zeilenumbruch hinweg finden
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

Text über Zeilenumbruch hinweg finden

beantworten | zitieren | melden

Hallo,

wie finde ich in einen Text mit Zeilenumbrüchen gemäß einer Vorlage ohne Zeilenumbrüch?
Beispiel:

...emil
und
luise...

möchte ich finden, habe als Suchmuster aber nur ...emil und luise... ohne Zeilenumbrüche.
Das heißt also, der Reguläre Ausdruck muss die Zeilenumbrüche zwischen den Wörtern akzeptieren. Im Regex klappt's. Ich habe das Suchmuster etwas kompliziert aufgebaut: Ich ersetze die Leerzeichem im Suchmuster durch @"([ \r\n]{1,5})" und vor Klammern im Text werden Backslashes eingefügt.
wie gesagt: Im RegexLab klappt's, in meinem Programm nicht. Programmzeile für das Regex-Muster:

string s_patt = Regex.Replace(textBox.Text.ToLower(), " ", @"([ \r\n]{1,5})").Replace("(", "\\(").Replace(")", "\\)");

Kann jemand helfen? Wäre toll!
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von MoaByter am .
Attachments
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Experte

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.878
Herkunft: Düsseldorf

beantworten | zitieren | melden

Der zweite Parameter muss das Pattern sein und nicht das Leerzeichen

Und das Pattern geht auch einfacher: \s+
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

??? hallo Palladin007,
was meinst du mit zweitem Parameter? Und mit '\s' findet der Regex doch nur die Leerzeichen. Die habe ich mir im Muster erspart, dadurchs wird's für mich leichter lesebar.
Was ich in meinem Text nicht gezeigt habe, ist die eigentliche Suche, aber dabei ist nix überraschendes:

Match m = Regex.Match(s_rtbtxt, s_patt, RegexOptions.Singleline);

Wie gesagt, im RegexLab funktioniert es genau so, wie ich's aufgebaut habe.
Dieser Beitrag wurde 3 mal editiert, zum letzten Mal von MoaByter am .
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Experte

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.878
Herkunft: Düsseldorf

beantworten | zitieren | melden

Zitat
was meinst du mit zweitem Parameter?

Dass der zweite Parameter das Pattern sein muss.
Regex.Replace(String, String, String)
Zitat
Und mit '\s' findet der Regex doch nur die Leerzeichen.
Nein.
RegExp \s Metacharacter

Aber ja, dein Pattern geht auch, ich sag nur, dass "\s+" auch reicht.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Öhm - ja, ich glaube, bezüglich des Patterns habe ich dich verstanden, hab's nämlich gerade mal ausprobiert:

string s_patt = Regex.Replace(tbQntTextSuche.Text.ToLower().Replace("(", "\\(").Replace(")", "\\)"), " ", "([\\s\\r\\n]+)"),
Also erst den Klammer.Replace, dann das Regex. Meintest du das so? Funktioniert nämlich. Deswegen hat das Muster - nur das Muster - im RegexLab funktioniert, da ich mit dem normalen Replace die Klammern wieder verändere. Fiel mir erst jetzt beim Debugging auf.

Tja, und die Sache mit dem '\s' wusste ich nicht. Erstaunlich, dass trotzdem alle meine anderen Regex so gut funktionieren. Ich dachte, ich wäre darin einigermaßen bewandert - Duning-Kruger-Effekt?

Also herzlichen Dank für deine Hilfe! Ich hatte so sehr im Netz gesucht und nur Unpassendes oder Müll gefunden (im_coder.com).

Gehab dich wohl, viel erfolg - MoaByter
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Experte

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.878
Herkunft: Düsseldorf

beantworten | zitieren | melden


string s_patt = Regex.Replace(textBox.Text.ToLower(), @"\s+", " ").Replace("(", "\\(").Replace(")", "\\)");
Kopiert und angepasst aus deiner ursprünglichen Frage.

Und "([\\s\\r\\n]+)" ist immer noch unnötig.
"\r" und "\n" erkennt "\s" von sich aus, dann brauchst Du keine Zeichenklasse mehr und die Gruppe brauchst Du sowieso nicht.
Ergo: \s+
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von Palladin007 am .
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Jau, Danke, habe ich umgeschrieben.
allerdings habe ich die Klammer auch noch mit 'nem Regex korrigiert:

string s_patt = Regex.Replace(Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1"), " ", "\\s+");
Vielleicht ginge es ja mit zweimaligem Replace wie in deiner Version schneller ... naja, so sieht's schöner aus.
Das '\s+' hat mir noch Kummer bereitet, ich hatte es zuerst in Klammern und die vergessen 'rauszunehmen, da ging die Geschichte nur mit einem Zeilenumbruch.
Jetzt läuft's aber, der Tipp ist Spitze, werde meine anderen Regex auch überpürfen. Da sind z.T. richtige Ungetüme drin, da ich unterschiedliche Texte bekomme.

Und ich hab's in eine extra Klassse gesetzt ... ... ... und es funktioniert trotzdem! :-)) Auch wenn's nur 67 Zeilen sind.
So lernt mann, naja: ich, immernoch dazu.

Also sei Bedankt, gehasbe dich wohl, ich muss inne Heia, mich müdet mittlerweile.
Viele Grüße - MoaByter (kommt von Moabit, mein Berliner Bezirk)
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Experte

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.878
Herkunft: Düsseldorf

beantworten | zitieren | melden

Ich verstehe den Sinn von dem Code nicht ...
Zwei mal Replace? Warum?
Wenn Du auch Klammern ersetzen willst, dann mach: [\s()]+

Und das "äußere" Replace ist immer noch falsch herum. Nochmal: Zähle die Parameter der Methode, der zweite Parameter muss das Pattern sein. Du versuchst ein Leerzeichen durch "\s+" zu ersetzen.

Und die Klammern *außerhalb* der eckigen Klammern sind eine Gruppe, die brauchst Du nur, wenn Du einen bestimmten Teil des Matches erreichen möchtest.

Für mich sieht das ein bisschen so aus, als würdest Du hier durch trial&error durch vor irren wollen.
Bei Regex wirst Du damit nicht glücklich, Du solltest dir dir Grundlagen anschauen.
[Artikel] Regex-Tutorial
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Scusi, die Antwort hat etwas gedauert, ich hatte heute reichlich anderes zu tun.
Zitat von Palladin007
Ich verstehe den Sinn von dem Code nicht ...
Zwei mal Replace? Warum?
Wenn Du auch Klammern ersetzen willst, dann mach: [\s()]+
Nein, die Klammern will ich nicht ersetzen, sondern maskieren. Der im WebBrowser selektierte Text dient ja als Regex-Muster und die Klammern würden dabei als Gruppe behandelt.
Ich habe die Regex jetzt einzeln aufgelistet:

    string s_patt = Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1");            // Escape-Zeichen für Klammern
    s_patt = Regex.Replace(s_patt, " +", "\\s+");                                           // Ersetzen der LeerZ. mit \s+
    s_patt = Regex.Replace(s_patt, "\r\n", "");
Zitat von Palladin007
Und das "äußere" Replace ist immer noch falsch herum. Nochmal: Zähle die Parameter der Methode, der zweite Parameter muss das Pattern sein. Du versuchst ein Leerzeichen durch '\s+' zu ersetzen.
Sind sie nicht. Ich ersetze ganz gezielt die Leerzeichen mit "\s+", denn genau dort befinden sich die Zeilenumbrüche (die ja dank deiner Tipps als Whitespace gelten). Und die ZU stören eben bei der Suche, das Programm findet dann den gesuchten Text nicht, da der eben keine ZU hat bzw. haben sollte (hat er leider manchmal doch, was merkwürdig ist).
Zitat von Palladin007
Und die Klammern *außerhalb* der eckigen Klammern sind eine Gruppe, die brauchst Du nur, wenn Du einen bestimmten Teil des Matches erreichen möchtest.

    Regex.Replace(tb_qts.Text.ToLower(), "([()])", "\\" + "$1")
Ja, aus der Gruppe ("([()])") - ist ja nur die Nr.1 - lese ich die gefundene Klammer aus - '(' oder ')' -, die dann mit Maskierung ("\\" + "$1") versehen wird: '\(' oder eben '\)'. Rückbezug oder oder so ähnlich.
Zitat von Palladin007
Für mich sieht das ein bisschen so aus, als würdest Du hier durch try&error durch vor irren wollen.
Bei Regex wirst Du damit nicht glücklich, Du solltest dir dir Grundlagen anschauen.
[Artikel] Regex-Tutorial
Ganz so schlimm ist es nicht, aber das RegexLab-Tool hilft nicht immer weiter, manches muss ich da probieren. Tatsächlich funktioniert es jetzt wie gewünscht bis auf eine kleine Kleinigkeit:
Absatzübergreifend findet er den Text auch jetzt nicht. Das dürfte an dem '\s+' liegen, denn in den Absatzumbrüchen stehen Sachen wie '<div> </div>' oder '<br>', eben keine WhiteSpace-Zeichen. Die könnte ich natürlich auch noch 'rausnehmen, aber das wird aufwendiger als nötig.
Regex-Tutorials habe ich einige, und auch gelesen, wenn auch nicht alles. Unter anderem habe ich die Funktionen von '\s' nicht gesehen - das wundert mich schon etwas. Ich weiß aber, dass ich über Regex noch längst nicht alles weiß. Denk' dran: Is'n altes Gehirn, dass sich nicht immer alles schnell merken kann. Ich brauche dazu Praxis, und die erarbeite ich mir gerade - unter anderem mit deiner Hilfe.

Also nochmals viele Dank, wenn ich mal Tipps für das 3-Schichten-Modell brauche, frage ich wieder, werde mich aber erstmal belesen.
einges habe ich jetzt schon ausgelagert, aber es gibt Methoden, die sehr intensiv an der GUI arbeiten, das ginge dann mit subclasses nur mit Invoke, was auf Dauer recht anstrengend ist.
Dennoch werde ich den Artikel gerne lesen.

tschüss bis demnächst mal - MoaByter
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von MoaByter am .
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Nochmal deutlicher:
Zitat
Sind sie nicht. Ich ersetze ganz gezielt die Leerzeichen mit "\s+", denn genau dort befinden sich die Zeilenumbrüche (die ja dank deiner Tipps als Whitespace gelten). Und die ZU stören eben bei der Suche, das Programm findet dann den gesuchten Text nicht, da der eben keine ZU hat bzw. haben sollte (hat er leider manchmal doch, was merkwürdig ist).
Ich gebe dem Regex mit dem '\s+' die Anweisung, die ZU in den Wortzwischenräumen zuzulassen bzw. zu ignorieren.
Die Länge des Originaltexts darf ich nicht ändern, da sonst die Indices nicht mehr stimmen.
Und: den Regex an den Originaltext anzupassen fand ich einfacher als umgekehrt.
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Experte

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.878
Herkunft: Düsseldorf

beantworten | zitieren | melden

Zitat
Der im WebBrowser selektierte Text dient ja als Regex-Muster und die Klammern würden dabei als Gruppe behandelt.

Du möchtest den String für Regex escapen?
In dem Fall: Regex.Escape(String) (Docs)
Das escaped dir alles, was eine gesonderte Bedeutung haben könnte.

Wenn einzelne Zeichen nachträglich doch eine Bedeutung haben sollen, musst Du das manuell machen.
Leerzeichen durch \s+ ersetzen: Simples Replace. Bedenke aber, dass \s mehr erkennt, als nur Leerzeichen.
Die Zeilenumbrüche entfernen: Auch simples Replace, mach das aber am besten mit Environment.NewLine (Docs)
Zitat
Absatzübergreifend findet er den Text auch jetzt nicht. Das dürfte an dem '\s+' liegen, denn in den Absatzumbrüchen stehen Sachen wie '<div> </div>' oder '<br>', eben keine WhiteSpace-Zeichen.
Für sowas ist Regex eigentlich ideal ^^
https://regex101.com/r/G7YqGz/1
Wie es genau aussehen muss und was Du damit machst, musst Du noch anpassen.

Und da siehst Du auch gleich ein wirklich gutes Regex-Tool.
private Nachricht | Beiträge des Benutzers
jogibear9988
myCSharp.de - Member



Dabei seit:
Beiträge: 638
Herkunft: Offenau

beantworten | zitieren | melden

Zitat von MoaByter
Ganz so schlimm ist es nicht, aber das RegexLab-Tool hilft nicht immer weiter, manches muss ich da probieren. Tatsächlich funktioniert es jetzt wie gewünscht bis auf eine kleine Kleinigkeit:
Absatzübergreifend findet er den Text auch jetzt nicht. Das dürfte an dem '\s+' liegen, denn in den Absatzumbrüchen stehen Sachen wie '<div> </div>' oder '<br>', eben keine WhiteSpace-Zeichen. Die könnte ich natürlich auch noch 'rausnehmen, aber das wird aufwendiger als nötig.

Was willst du denn genau machen? Vlt. wäre ja ein HTML (wie AngleSharp) parser besser geeignet
cSharp Projekte : https://github.com/jogibear9988
private Nachricht | Beiträge des Benutzers
MoaByter
myCSharp.de - Member



Dabei seit:
Beiträge: 68
Herkunft: Berlin

Themenstarter:

beantworten | zitieren | melden

Zitat von Palladin007
Du möchtest den String für Regex escapen?
In dem Fall: Regex.Escape(String) (Docs)
Das escaped dir alles, was eine gesonderte Bedeutung haben könnte.
...
Leerzeichen durch \s+ ersetzen: Simples Replace. Bedenke aber, dass \s mehr erkennt, als nur Leerzeichen.
Die Zeilenumbrüche entfernen: Auch simples Replace, mach das aber am besten mit Environment.NewLine (Docs)
...
Für sowas ist Regex eigentlich ideal ^^
https://regex101.com/r/G7YqGz/1
Wie es genau aussehen muss und was Du damit machst, musst Du noch anpassen.

Und da siehst Du auch gleich ein wirklich gutes Regex-Tool.
Das sind doch mal zwei exzellente Tipps. Regex.Escape kannte ich noch gar nicht, muss also mein Wissen über Regex auf jeden Fall aktualisieren.
Bedankt!
Mittlerweile funktioniert's wie gewünscht, dein Tipp mit "\s" war ideal - eben weil das mehr als Leerzeichen erkennt.
Nun will ich die ganze Sache noch etwas ändern und erweitern, wobei mir das Regex.Escape durchaus helfen könnte.
Nochmals bedankt!
Zitat von jogibear9988
Was willst du denn genau machen? Vlt. wäre ja ein HTML (wie AngleSharp) parser besser geeignet
Das HTML ist nicht das Problem, der ganze Kram liegt nur in HTML vor, deswegen die vielen Tags darin. Die müssen allerdings auch erkennt werden, was gelungen ist. Dennoch oder trotzdem oder wie auch immer Danke für deine Antwort.
private Nachricht | Beiträge des Benutzers