Regex - Garantiert jeden String escapen



  • Hallo Communitionen!

    Bisher nutzte ich:

    string fragment1 ...
    Regex regFrag1 = new Regex(Regex.Escape(fragment1));
    

    um die Sonderzeichen im string zu escapen.

    Z.Z. zeigt meine App ein anomales Verhalten.
    Ich durchsuche einen Richtext nach dem vorgegeben regFrag1, um einen TextPointer zu finden. Läuft nicht mehr zuverlässig.

    Regex.Escape(fragment1) escaped aber nur einen minimalen Zeichensatz:
    \ ( ) [ { | * ? + ^ $ . # [ Leerzeichen ]

    Das Spektrum der Sonderzeichen, die escaped werden müssten, ist aber größer:
    https://msdn.microsoft.com/de-de/library/4edbef7e(v=vs.110).aspx

    \d: eine Ziffer(entspricht[0-9])
    \D: ein Zeichen, welches keine Ziffer ist (auch:[^\d])
    \w: ein Buchstabe, eine Ziffer oder der Unterstrich, also [a-zA-Z_0-9](und evtl. weitere Buchstaben, z.B.Umlaute)
    \W: ein Zeichen, das weder Buchstabe noch Zahl noch Unterstrich ist (entspricht [^\w])
    \s: Whitespace(Leerraum); meistens die Klasse der Steuerzeichen \f,\n,\r,\t und \v
    \S: ein Zeichen, das kein Whitespace ist [^\s]

    und

    In neueren Implementationen von Regex gibt es zusätzlich folgende POSIX
    -Klassen.Anmerkung:Die Regex-Engine von .NET unterstützt keine POSIX-Klassen!
    [:alnum:]:Alphanumerische Zeichen:
    [:alpha:]und
    [:digit:]Ziffern: 0, 1, 2,... bis 9.
    [:alpha:]:Buchstaben:
    [:lower:]:Kleinbuchstaben: nicht notwendigerweise nur von a bis z.
    [:upper:]:Großbuchstaben: nicht notwendigerweise nur von A bis Z.
    [:blank:]:Leerzeichen und Tabulator.
    [:cntrl:]:Steuerzeichen. Im ASCII sind das die Zeichen 00 bis 1F, und 7F (DEL).
    [:digit:]:Ziffern: 0, 1, 2,... bis 9.
    [:graph:]:Graphische Zeichen: [:alnum:]und[:punct:].
    [:print:]:Druckbare Zeichen: [:alnum:],[:punct:]und Leerzeichen.
    [:punct:]:! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ ] ^ _ ` { | } ~ .
    [:space:]:Whitespace: Horizontaler und vertikaler Tabulator, Zeilen -und Seitenvorschub, Wagenrücklauf und Leerzeichen.
    [:xdigit:]: Hexadezimale Ziffern: 0 bis 9, A bis F, a bis f.

    Ich habe leider keinerlei Restriktionskontolle über den RichText, sowie den string und muss mit Allem rechnen.
    Wie bekomme ich mein fragment1 jetzt kindersicher escaped? - Oder ist er kindersicher escaped? 😕

    Danke! 🙂



  • Ich verstehe das Problem nicht.
    Wenn \ escaped wird, dann kann in dem String keine "Steuersequenz" mehr erkannt werden die mit \ anfängt.
    Und wenn [ escaped wird keine mehr die mit [ anfängt.
    Das deckt die ganze \d , [:alnum:] etc. aus deiner Liste ab.

    Ich durchsuche einen Richtext nach dem vorgegeben regFrag1, um einen TextPointer zu finden. Läuft nicht mehr zuverlässig.

    Leider viel zu schwammig/uneindeutig beschrieben. Kann man fast nix dazu sagen. Wenn dann müsstest du schon Code zeigen. Und was du mit "Richtext" meinst weiss ich auch nicht. Meinst du wirklich ein Dokument im RichText Format? Dass man da drinnen nicht einfach so nen Text suchen kann ist dir hoffentlich klar. Also können kann man schon, man wird ihn bloss nicht unbedingt finden, wenn z.B. mittendrin irgendwelche Formatierungsanweisungen stehen.

    Und du schreibst "nicht mehr". D.h. es ging schonmal? Wenn ja, easy: Was hast du seit dem geändert?

    ps: Erst jetzt auf den Autor geguckt. Klassischer Prof84 halt 😃



  • Für weitere Lesebehinderten:

    Prof84 schrieb:

    Regex.Escape(fragment1) escaped aber nur einen minimalen Zeichensatz:
    \ ( ) [ { | * ? + ^ $ . # [ Leerzeichen ]

    Das Spektrum der Sonderzeichen, die escaped werden müssten, ist aber größer:
    https://msdn.microsoft.co ....... dbef7e%28v=vs.110%29.aspx

    Typischer Hustbaer! Versteht nix... 🙄



  • Hat sich erledigt.

    Durch das Escapen wurde der BufferSize/CacheSize von

    = new Regex(Regex.Escape(fragment1), RegexOptions.Compiled | RegexOptions.IgnoreCase)
    

    zu sehr aufgebläht. Deshalb spinnte er.



  • Prof84 schrieb:

    Für weitere Lesebehinderten:

    Prof84 schrieb:

    Regex.Escape(fragment1) escaped aber nur einen minimalen Zeichensatz:
    \ ( ) [ { | * ? + ^ $ . # [ Leerzeichen ]

    Das Spektrum der Sonderzeichen, die escaped werden müssten, ist aber größer:
    https://msdn.microsoft.co ....... dbef7e%28v=vs.110%29.aspx

    Typischer Hustbaer! Versteht nix... 🙄

    Und du bist denkbehindert!
    Alter Schwede, wie kann man nur so bescheuert sein?

    Ich hab mir den von dir verlinkten Artikel schon durchgelesen. Und da ist nix zu finden was Regex.Escape nicht escapen würde. Du bist einfach nur ein arroganter dummer Wixer.



  • Da Thema ist leider noch nicht durch!

    Ich habe jetzt Expresso runtergeladen, um die Regex zu vergleichen.
    Das Programm nutzt nur die .net.

    Vorab Test:

    string o_output = ... 
    // x-beliebige Testvektorbildung aus einem Textfeld das jedes Unicodezeichen erlaubt - UTF-32 aber meistens UTF-8 - primär SW-Code.
    string r_output = Regex.Escape(r_output);
    string une_output = Regex.Unescape(out_string);
    

    Wie zu erwarten, ist immer o_output = une_output bei allen Vektoren;

    Allerdings ist das matching mit der captured o_output im Textfeld in vielen Fällen dann nicht mehr möglich. Die erste Anomalie, die mir aufgefallen ist, war das der Regex.Escape-Ausdruck mit den geschweiften Klammern {} ummantelt wurden.
    Der Expresso-Analyator erkennt die geschweifte Klammer als Teil des suchenden Strings. - Daher vielleicht auch kein Matching mit den dort eingegeben Input-Text.
    Ich habe auch versucht den String mit "^ ... $" oder mit @ zu erweitern oder die Klammen im Tool wegzulassen. Auch die RegexOptions.IgnorePatternWhitespace wurde einbezogen. Alles ohne Erfolg.
    Mein Verdacht ist, das die escapten Leerzeichen nicht richtig geparst werden. mit den .net Regex Funtionen.

    Orginal Input Textfeld:

    Regex regFrag1 = new Regex(/*@"^" +*/ Regex.Escape(fragment1)/* + "$"*/);
                Regex regFrag2 = new Regex(/*@"^" + */Regex.Escape(fragment2), RegexOptions.IgnorePatternWhitespace/* + "$"*/);
    
                Match match = null;
                int foundIdx = 0;
                int matchCount = 0;
    
                while (_docStart != null && _docStart.CompareTo(_endCharPos) < 0)
                {
                    /*MessageBox.Show(_docStart.GetPointerContext(LogicalDirection.Forward).ToString()
                                    + "\rreqFrag: " + regFrag1 + "\r"
                                    + "Reescaped: " + Regex.Unescape(fragment1)); */
                    if (_docStart.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text)
                    {
                        if (!matchFrag1Found)
                        {
                            match = regFrag2.Match(_endCharPos.GetTextInRun(LogicalDirection.Forward).ToString());
    
                            //match = regFrag1.Match(_docStart.GetTextInRun(LogicalDirection.Forward));
                        }
    

    Gebildet wurde z.B. das regFrag2 = {\ \(_docStart\ !=\ null\ &&\ } aus
    fragment2 = " (_docStart != null && "

    Der Analysator erkennt "{ (_docStart != null && }" , mit und ohne Anführungszeichen, auf "Run Mathes" und trotz Änderungen der Optionen erfolgt kein Matching.

    Ziel ist es, dass das Matching im Richtext den Pointer zurückgibt, an der ersten Stelle, an dem das Pattern gefunden wurde in eine festgelegten Textbereich.



  • Prof84 schrieb:

    Da Thema ist leider noch nicht durch!

    Für Dich nicht.
    Aber für uns.
    Frag einen Azubi des Unternehmens für das Du arbeitest.



  • Vielleicht hättest Du ihm besser auf englisch geantwortet?



  • @volkard
    Ich glaub sogar dass dieser Beitrag nach deiner Logik nen Sinn macht.



  • volkard ist definitiv ein Autist!



  • Ich hab mir den von dir verlinkten Artikel schon durchgelesen. Und da ist nix zu finden was Regex.Escape nicht escapen würde. Du bist einfach nur ein arroganter dummer Wixer.

    👍


Anmelden zum Antworten