Suchen von Platzhaltern in {{}}-Klammer-Definitionen

  • VB.NET

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von siycah.

    Suchen von Platzhaltern in {{}}-Klammer-Definitionen

    Moin!

    ich habe Dateien die wie folgt aufgebaut sind.


    <p>mit Bescheid vom {{DatumAufforderung}} wurden Sie aufgefordert, ......</p>

    {{Fusszeile}}

    {{DSGVO}}


    Darin sind Platzhalter durch doppelte geschweifte Klammern definiert.

    Es können diese in Texten vorkommen oder auch nur in einer Zeile alleine.

    Jede Zeile durchlaufen und dann {{ suche und dann die nächste folgende }} suchen. Aus der Differenz dann den Wert ermitteln oder gibt es einen eleganterten We?

    Am Ende möchte ich eine Liste der Platzhalter haben.

    Gruß Jan
    Moin!

    erst einmal vielen dank.

    Auch wenn es nicht direkt die Fragestellung mehr ist hänge ich mich hier doch einfach weiter rein.

    Wie komme ich nun an die Werte - in dem Link klinkt das ja sehr gut.

    Meine Idee wäre jetzt

    VB.NET-Quellcode

    1. Dim pattern As String = "\{\{.+?\}\}"
    2. Dim input As String = "<p>mit Bescheid vom {{DatumAufforderung}} wurden Sie aufgefordert, ......</p>"
    3. Dim m As Match = Regex.Match(input, pattern, RegexOptions.IgnoreCase)


    Dann jede Zeile durchlaufen - aber wie kommt man an die Ergebnisse, wenn mehrere in einer Zeile sind??

    Gruß Jan

    jan99 schrieb:

    mehrere in einer Zeile
    findest Du mit der Match.NextMatch Methode: learn.microsoft.com/de-de/dotn…tch?view=netframework-4.8
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    jan99 schrieb:

    Am Ende möchte ich eine Liste der Platzhalter haben

    Die gibts unter Regex.Matches statt Regex.Match. Man kann mit Lookarounds sogar die Klammern aus den Matches entfernen, also das er wirklich nur das dazwischen erfasst.
    (?<={{)[^}]+(?=}}).
    Mit Capturing Groups wäre das Pattern einfacher dafür wäre der Code ein bissle länger.

    ErfinderDesRades schrieb:

    Zeichen zu escapen
    Regex ist da ganz eigen manchmal wollen die nur die Klammer_auf escaped haben und bei Klammer_zu ist es egal. Und jede Version ist dann auch noch anders

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    @Eierlein unnötig in speziell genau diesem Fall womöglich schon, ich würde trotzdem immer empfehlen, jegliche Metazeichen zu escapen wenn man sie als Literale benutzen möchte (klick). Das beseitigt zum einen Kompatibilitätsprobleme und zum anderen kann der Pattern so flexibler erweitert werden. Schlampige Pattern zu basteln weil man sich Tastendruck sparen kann steht denke ich in keinem Verhältnis^^


    Link :thumbup:
    Hello World

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Link“ ()

    Bitte nicht falsch verstehen Lookarounds sind eine tolle Sache wenn man sie an den richtigen Stellen einsetzt. Für das oben genannte Problem sind Sie aber wie "mit Kanonen auf Spatzen schießen". Du kannst ja mal ne CapturingGroup und nen Lookaround bei regex101 gegeneinander antreten lassen mit dem besagten Problem.
    Die Performance von RegEx ist iwie schon ein gern diskutiertes Thema, oder? Ja es stimmt, Lookarounds sind heavier als einfach die Capturing Groups zu fetchen und die Matches dann durch ein Trim zu jagen um die curly braces loszuwerden. Speziell ranzig ist RegEx vor allem in Verbindung mit Datenbanken - was mit LIKE raussuchen zu müssen ist schon madig, aber dann noch ein RegEx ... überaus unangenehm (zumeist liegt der Notwendigkeit hierfür aber schon ein fehlerhaftes Datenbankdesign zugrunde).

    Regex ist da ganz eigen manchmal ..

    Nö, es gibt einfach verschiedene Arten von RegEx-Engines (ich persönlich favorisiere PCRE). Grundsätzlich lieber einmal mehr escaped als einmal zu wenig.

    Es gibt keine Kanonen in Regex in dem Sinne

    RegEx IST die Kanone ;)

    Fakt is, RegEx ist halt geil, und wenn man die Regeln verstanden hat, macht's einfach nur Spaß es zu benutzen. Super für das finden oder Verarbeiten von Texten oder zum greppen von Daten auf der Shell.

    Ich finde überhaupt auch das Performance Argument komplett unnötig. RegEx ist hier Performance-Nutzen-Technisch der beste Weg um das Problem zu lösen. Oder will man den String manuell tokenisieren um an die gesuchten Teilstrings zu kommen? - Nein, sicher nicht. Über Performance-Optimierung kann man sich wenn man geil drauf ist auslassen in Fällen wo es Relevanz hat, das heißt wenn man Gigabyty große Dateien parsen oder ein RegEx SELECT auf Tabellen mit Millionen von Rows absetzen muss. Das ist hier nicht der Fall, und es interessiert sicher auch keinen ob die Ergebnisse eine Millisekunde schneller da sind.

    Performance ist in den allermeisten Fällen in denen man RegEx benutzt völlig irrelevant.

    Für das wofür man RegEx die meiste Zeit braucht kann man jederzeit die Pattern so komplex und ranzig zusammenschustern wie man lustig ist, man bemerkt bei der Ausführung keinen nennenswerten Unterschied. Es interessiert einfach nicht. Man kann RegEx immer und für alles verwenden und muss kein schlechtes Gewissen haben, auch nicht wenn einer mit seinem Performance-Mimimi dahergelaufen kommt.

    Wann man RegEx nicht verwenden soll:
    - wenn man es mit übertrieben großen Datenmengen zu tun hat
    - wenn man versucht, RegEx zu verwenden für Aufgaben die reguläre Ausdrücke nicht leisten können oder für es Parser gibt (verschachtelte Strukturen, XML oder HTML)

    Für jeden anderen Fall der hier nicht gelistet ist, kann man jederzeit RegEx nehmen, warum auch nicht. Außer es gibt eine einfachere Möglichkeit (zB wenn Substring o.ä. ausreicht).


    Link :thumbup:
    Hello World
    @Haudruferzappeltnoch RegEx wurde auch genau dafür entwickelt, genau so wie Wildcards in der Shell dafür entwickelt wurden, schnell mit Dateien umzugehen.

    Die Alternativen hängen doch ganz davon ab, was du machen willst?
    Willst du JSON, YAML, XML und Co parsen: nimm einen Parser.

    In deinem Fall reicht ein ganz einfacher Regex mit einer Lookup-Table.

    Etwas ganz schlichtes wie:

    C#-Quellcode

    1. ​using System.Collections.Generic;
    2. using System.Text.RegularExpressions;
    3. class MyTestClass {
    4. readonly Regex m_myRegex = new Regex(@"[}]{2}[\s\S]+[}]{2}", RegexOptions.Compiled | RegexOptions.CultureInvariant);
    5. static Dictionary<string, Func<string>> MyLookup = new Dictionary<string, Func<string>> {
    6. { "Date", DateTime.Now.ToLongDateString },
    7. { "Time", DateTime.Now.ToLongTimeString },
    8. { "MyWeirdValue", () => new Random().NextInt64().ToString() }
    9. };
    10. void PerformLookup(ref string myText) {
    11. foreach (Match match in m_myRegex.Matches(myText)) {
    12. var id = match.Value.Trim('{', '}');
    13. if (MyLookup.ContainsKey(id)) {
    14. myText.Replace(match.Value, MyLookup[id]());
    15. }
    16. }
    17. }
    18. }


    wäre in deinem Fall mMn ganz angebracht. Die genauen Implementierungsdetails sind ja erstmal egal und mit einem ganz einfachen Regex verstehst du auch in drei Wochen noch, was du mit deinem Code mal erreichen wolltest.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    Was meinst du "in meinem Fall"? Mein Fall ist quasi wie es TE schon gemacht hat, nur eben + die zwei Punkte die ich nannte. Siehe Post 3

    VB.NET-Quellcode

    1. Dim pattern As String = "(?<={{)[^}]+(?=}})"
    2. Dim input As String = "<p>mit Bescheid vom {{DatumAufforderung}} wurden Sie aufgefordert, ......</p>"
    3. Dim m = Regex.Matches(input, pattern, RegexOptions.IgnoreCase)


    @Haudruferzappeltnoch Du warst mit letzterem nicht gemeint. Das hätte ich klarer schreiben sollen.

    In dem Fall des TE würde ich es so implementieren. Ganz simpel mit kleinem RegEx, ohne Schnickschnack.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)