Reguläre Ausdrücke Sammlung

  • oder so...

    :rofl: Kreativ, geb ich zu.

    Aber _WinAPI_IsInternetConnected returnt auch True wenn eine Lan-Verbindung besteht.

    Du kannst also zum Router verbunden sein (der Router kann aber alle Anfragen blockieren und es ist dennoch True, habs gerade getestet.)

    Ganz zu schweigen davon, ob der Webserver überhaupt erreichbar ist oder nicht.

  • Aber _WinAPI_IsInternetConnected returnt auch True wenn eine Lan-Verbindung besteht.

    Dann ist die Funktion unbrauchbar... dann halt so... 8o

  • In der FF.au3 hat Stilgar die URL-Validierung so gelöst:

  • Hier Beispiele zu sammeln, kann eine Hilfe sein für Leute, die regex'e verstehen.

    Für alle anderen ist es, als würden sie ein paar Lautfolgen auswendig lernen für den Urlaub im Ausland, ohne auch nur die einzelnen Worte darin auseinanderhalten zu können, geschweige denn den Satzbau zu verstehen.

    Regular Expressions ist eine Sprache, mit der man Suchmuster für Zeichenfolgen (Texte, Programmcode, Daten, etc.) definieren kann.

    Hilfreich zum Erlernen sind Seiten wie https://regex101.com/ , um seine Ausdrücke auszuprobieren, und aufgrund der farbigen Markierungen der Teilausdrücke und der Fundstellen verstehen zu lernen, welcher Teilausdruck für die Erkennung welches Textes zuständig ist.

    Neben der StringRegExp Seite in der Hilfedatei sind auch die Kommentare zu regex in der PHP-Hilfe online oft hilfreich.

    Wer die Sprache nicht lernt, sondern nur fertige Ausdrücke kopiert, wird nie weiter kommen, genau wie "dumme" Maschinen, die auch immer nur das können, was ihnen jemand "beigebracht" hat. Regex'e sind aber ein SEHR mächtiges Werkzeug, mit dem man sich viel Arbeit sparen kann, nicht nur bezüglich der Länge des eigenen Programmcodes, sondern z.B. auch bei der automatisierten Verarbeitung riesiger Text/Datenmengen.

    Das Sinnvollste wäre es wohl, die Erklärungen in der Hilfe hier zu diskutieren und entspr. Fragen von Laien ausführlicher zu erklären, incl. Beispielen.


    EDIT BugFix: War vom Poster gelöscht worden. Wiederhergestellt.

    Einmal editiert, zuletzt von BugFix (19. November 2018 um 18:52)

  • Regular Expressions ist eine Sprache, ...

    Ne, ne, ne und ne... Deutsch, Englisch, AutoIt, Python und HTML sind Sprachen, aber Regular Expressions ist definitiv keine!

    Ein regulärer Ausdruck (englisch regular expression, Abkürzung RegExp oder Regex) ist in der theoretischen Informatik eine Zeichenkette, die der Beschreibung von Mengen von Zeichenketten mit Hilfe bestimmter syntaktischer Regeln dient.

    Wer die Sprache nicht lernt, sondern nur fertige Ausdrücke kopiert, wird nie weiter kommen, genau wie "dumme" Maschinen, die auch immer nur das können, was ihnen jemand "beigebracht" hat.

    Das sehe ich anders. Wenn ich öfters weite Strecken überwinden muss, aber nicht die Lust, Zeit oder Möglichkeit habe, zu erlernen mir selbst ein Auto zu bauen, dann leihe/lease/kaufe ich mir eins. Das bringt mich auch ans Ziel!

    Das Sinnvollste wäre es wohl, die Erklärungen in der Hilfe hier zu diskutieren und entspr. Fragen von Laien ausführlicher zu erklären, incl. Beispielen.

    Nein, das finde ich gar nicht sinnvoll. Dieser Thread ist dafür da, um Reguläre Ausdrücke zu sammeln, nicht aber um ihn mit endlosen Diskussionen/Fragen zu füllen. Dafür gibt es hier sicher andere Threads oder Seiten im Internet, die einen zu diesem Thema erleuchten können.

    • Offizieller Beitrag

    fakeraol:

    Bitnugger hat ja schon darauf hingewiesen: Dieser Thread ist, wie schon der Titel "Reguläre Ausdrücke Sammlung" vermuten läßt, eine Zusammenstellung unserer geistigen Aktivitäten zu diesem Thema.

    Was ist der Sinn einer Sammlung? Na sonnenklar: Jeder kann sich dort bedienen, ohne selbst das Rad neu erfinden zu müssen. Deiner Logik nach, sollten wir dann die UDF aus den Includes entfernen, weil es hilfreicher ist, dass sich jeder eine eigene Lösung zu häufigen Problemen bastelt?! :Face:

    Ich glaube, du hast noch nicht verinnerlicht, aus welchem Grunde wir dieses Forum gestalten.

  • Ich meine das hier:

    franzp: "Aber ich kapier das einfach nicht."

    Alina: "Willkommen im Club !"

    diepfeile: "Wofür sind die '/' am Anfang und am Ende? Zudem funktioniert das bei mir nicht, obwohl ich die '/' weggelassen habe und das fehlende 'z' ergänzt habe."

    Bitnugger: "Wofür die '/' am Anfang und Ende sind, kann ich dir nicht sagen."

    Klar könnt Ihr hier eine Sammlung machen, und die kann dann auch von Leuten genutzt werden, die überhaupt nicht verstehen, was sie da benutzen.

    Allerdings werden die dann, wie man an diepfeile's Beitrag sieht, auch schon an der kleinsten Anpassung scheitern, und hier jedes mal nachfragen müssen.

    Wer lieber versucht, mit 100 Zeilen String-Funktionen die Power von regulären Ausdrücken nachzubilden, kann sich das auch antun.

    Bitnugger

    Reguläre Ausdrücke beschreiben eine Familie von formalen Sprachen und gehören damit zur theoretischen Informatik. Diese Sprachen, die regulären Sprachen, befinden sich auf der untersten und somit ausdrucksschwächsten Stufe der Chomsky-Hierarchie (Typ 3). Sie werden erzeugt durch reguläre Grammatiken.

    Ist aber nebensächlich, wie man das nennt.

    Evtl. hilft das hier dem einen oder anderen schon weiter:

    https://wiki.selfhtml.org/wiki/JavaScript/Objekte/RegExp

    https://danielfett.de/de/tutorials/t…lare-ausdrucke/

    http://www.regenechsen.de/phpwcms/index.php?regex_allg

    Die UDF haben natürlich ihre Berechtigung, Mein Hinweis bezog sich aber darauf, daß RegEx ein unheimlich mächtiges Werkzeug sind, und daß es sich für jeden zu lernen lohnt , der nicht nur einmalig eine Lösung für ein Problem zusammenhacken will. diepfeile nützt die Sammlung so bisher wohl garnichts, weil er sie nicht mal copy&paste anwenden kann.

    Zu den "/" am Anfang und Ende der Regex:

    Zusätzlich zum eigentlichen reg. Ausdruck kann man dem Interpreter noch Optionen mitgeben, die die Interpretation des Ausdrucks beeinflussen, wie z.B. den Parameter s, der das Verhalten so ändert, daß nicht nur bis zum nächsten Zeilenumbruch gesucht wird, sondern über Zeilenumbrüche hinweg.

    Der eigentliche Ausdruck wird deshalb in 2x (Anfang und Ende) das gleiche Zeichen eingeschlossen. Das muß garnicht immer ein "/" sein. Empfehlenswert ist es, ein Zeichen zu nehmen, das in dem Ausdruck sonst nicht vorkommt, z.B. "#".

    Die Optionen in (? ) einzuschließen, ist AutoIt-Syntax. in PHP oder Javascript z.B. kommen die Optionen einfach hinter die, den Ausdruck umschließenden Zeichen.

    EDIT BugFix: War vom Poster gelöscht worden. Wiederhergestellt.

    Einmal editiert, zuletzt von BugFix (19. November 2018 um 18:55)

  • Ich bitte, den ganzen Mist in einen Thread zu verschieben, der Diskussion über den Thread "Reguläre Ausdrücke Sammlung" heißt. Sollen sie sich dort streiten. Kann doch nicht sein, dass jemand wie fakeraol - der aktuell 57 Beiträge im Forum hat - den Thread kapern kann.

    Natürlich habe ich mich nun auch mit einem Thread-Theam-fernen Beitrag beteiligt und das Ganze damit schlimmer gemacht. Ich bitte aber explizit um Verschieben oder Löschen meines Beitrags durch die Mods.

    Grüße autoiter

    • Offizieller Beitrag

    Ich habe eine interessante Fähigkeit der PCRE-Engine in einem Tut entdeckt: SKIP & FAIL.

    Was bedeutet das? Das ist eine Anweisung bei einem Match, diesen zu überspringen (SKIP), zu ignorieren (FAIL) und ab dieser Position weiter zu suchen. Das erleichtert einige Pattern, da man einiges an Capturing vermeiden kann.

    Ich habe mal ein Bsp. erstellt.

    Bsp. Blacklist

    In diesem Fall ergibt sich folgendes Pattern:

    "\b(?:Peter|Paul|Maria)\b(*SKIP)(*FAIL)|([a-zA-ZäöüÄÖÜß]+)"

    Gehen wir es Schritt für Schritt durch:

    - auf der linken Seite sind die Blacklistwerte, Pipe-getrennt

    \b(?:Peter|Paul|Maria)\b  - die Begriffe müssen als ganzes Wort gefunden werden (Paul matcht nicht Paula)

    \b(?:Peter|Paul|Maria)\b - die Begriffe der Blacklist werden nicht in einem Capture aufgefangen

    \b(?:Peter|Paul|Maria)\b - die Begriffe durch Pipe als ODER-Abfrage

    (*SKIP)(*FAIL)  - die Anweisung den Match zu überspringen und zu ignorieren

    - auf der rechten Seite das Pattern für die abzufragenden Einträge

    ([a-zA-ZäöüÄÖÜß]+) - das Ergebnis in einem Capture

    ([a-zA-ZäöüÄÖÜß]+) - Zeichenklasse, alle Zeichen dürfen mehrfach auftreten

    ([a-zA-ZäöüÄÖÜß]+) - alle Buchstaben des deutschen Alphabets

    Ich finde diese Variante hochinteressant. Vielleicht könnt ihr ja auch was damit anfangen.

    • Offizieller Beitrag

    Wenn man längere Pattern schreibt, sind Kommentare sehr sinnvoll (gerade, um auch einem anderen die Möglichkeit zu geben, das Pattern nachzuvollziehen).

    Hier mal ein Pattern zum Splitten eines Windows/UNC-Datei-Pfades in: Lw | Ordner[optional] | Datei-mit-Erweiterung | Dateiname | Erweiterung.

    Die jeweilige Capturegroup beginnt immer mit einem Kommentar, der auf den Inhalt der Group verweist:

    '^(?i)((?#drive)[a-z]:|\\\\[a-z0-9]+)\\((?#folder)[^/:*?"<>|\r\n]*\\)?((?#file)((?#filename)[^\\/:*?"<>|\r\n]+)\.((?#extension)\w+))$'

    Wir erhalten ein Ergebnisarray mit 5 Elementen (bei z.B. "Lw:\Datei.ext" bleibt Ordner leer):

  • Darf ich bitte mal an autoiters Wunsch in # 29 erinnern - das sollte man schon umsetzen - danke

    Gruß

    Peter

    Hinweise auf Suchmaschinen finde ich überflüssig - wer fragt hat es nicht gefunden oder nicht verstanden. Die Antwort gibt sich oftmals schneller als der Hinweis auf Dr. Goggle & Co.

    Ab 19-10-22 ergänzt um:

    Die Welt wird nicht bedroht von den Menschen, die böse sind, sondern von denen, die das Böse zulassen. (Albert Einstein)

  • ReadFunctionHeads()

    Heute füge ich gleich mehrere RegExp's, quasi eine Sammlung, zur Sammlung hinzu. Die RegExp's habe ich in der Funktion ReadFunctionHeads() gekapselt und ein Demo inklusive einer Test-Datei erstellt. Die Funktion verwendet die RegExp's, um aus einer au3 Datei alle gültigen Kopfzeilen von Funktions-Deklarationen auszulesen, davon die Funktions-Namen und deren Parameter-Liste herauszufiltern und in einer aus der AutoIt Hilfe gewohnten Schreibweise darzustellen. Zum Beispiel:

    ExampleFunction ( Const $sMsg1, ByRef $iVar1, $iVar2 = 0, $bVar = True )  


    Mein Dank geht an alle, die sich an den Postings beteiligt und/oder am Code mitgearbeitet haben: Bitnugger, alpines, AspirinJunkie, Musashi und BugFix. (Sollte ich jemanden vergessen haben, bitte melden.)

    Viel Spaß damit. Professor Bernd.

    Wie es entstanden ist

    Im Rahmen meines PSPad4AutoIt3 Projekts sollte der CallTipViewer erweitert werden, um CallTips für OUDFs (own user defined function) anzeigen zu können. Deshalb hatte ich mit einer Funktion begonnen, die alle Funktionsköpfe aus einer .au3 Datei liest. Bitnugger hat mich dann auf den Geschmack mit RegExp's gebracht, da die deutlich schneller sind, als StringReplace, StringStripWS, Schleifen und Co.

    Dann öffnete ich den Thread "RegExp: Space um Zeichen setzen - mehrfache Spaces ersetzen - Zeilen mit Begriff behalten" in dem diese 3 Aufgaben mithilfe von RegExp's gelöst werden sollten. Mehr als ein Mal habe ich Kopfschmerzen von den komplexen Regeln der RegExp's bekommen. BugFix hat meine Zweifel zerstreut, ob die RegExp's was taugen, die ich erarbeitet hatte. Vorallem alpines hat in dem Thread mit einer Engelsgeduld :saint: Licht in das Mysterium gebracht und mir vieles erklärt.

    Weitere Filter wollte ich dann auch mit RegExp's erledigen. Bei meiner Recherche fand ich eine RegExp von AspirinJunkie, die jedoch mein Script zum Abstürzen brachte. Ich öffnete einen zweiten Thread "RegExp: Verschachtelte Block-Kommentare entfernen - Char nicht-in-String ersetzen" und frage AspirinJunkie nach einer angepassten RegExp. Dabei kam nicht nur ein Pattern zum Entfernen von verschachtelten Block-Kommentaren raus, sondern auch ein Pattern um Zeichen nur außerhalb von Strings zu finden, also wenn sie nicht in Anführungszeichen stehen.

    Anhand der wirklich genialen Pattern von AspirinJunkie konnte ich zudem meine eigenen RegExp-Fähigkeiten verbessern. Alle Pattern und viel Hirnschmalz habe ich in der Funktion ReadFunctionHeads() kombiniert und sie läuft richtig performant. :)

    Bitte beachten: Die RegExp's sind aufeinander abgestimmt und funktionieren alleine nur bedingt.
    Info zur Test-Datei

    Die Test-Datei "_test file.au3" ist ein Sammelsurium an normalen Funktionen (selbst geschrieben oder aus der AutoIt Hilfe) und teilweise sinnlosen, an den Haaren herbeigezogenen, unfertigen Funktionen. Damit sollen auch Testfälle abgedeckt werden, die in der Realität eher selten vorkommen. Die RegExp's sollten sie ausfiltern und verwerfen.

    Fragen, Anregungen, Diskusionen verlagern wir am besten in den Thread "RegExp: Verschachtelte Block-Kommentare entfernen - Char nicht-in-String ersetzen".

  • Es hatten sich zwei kleine Bugs eingeschlichen, die ich entfernt habe: Funktionen die in der letzten Zeile abgeschlossen wurden (EndFunc), wurden nicht erkannt, Erkennung für #Region/#EndRegion war nur für @LF ausgelegt. Das aktualisierte Demo habe ich im Posting #36 hochgeladen.

    Damit die User benachrichtigt werden, die das Demo schon heruntergeladen hatten, habe ich diese Mitteilung in ein eigenes Posting geschrieben.

    Bernd.

    Wenn jemand sagt: "Das geht nicht!" Denke daran: Das sind seine Grenzen, nicht deine.

    Einmal editiert, zuletzt von Professor Bernd (6. Juli 2020 um 14:56)

  • Müssten die #region-#endregion nicht auch sowieso durch das Pattern "Alle Zeilen die nicht mit Func oder EndFunc angfangen" entfernt werden?

    Also wenn ja - warum dann eine Extra-Behandlung hierfür?

    Zum Thema mehrfachen Leerraum entfernen: Es muss nicht immer RegEx sein..: StringStripWS(..., 4)

    • Offizieller Beitrag

    Reguläre Ausdrücke übersichtlich darstellen

    Zur Übersichtlichkeit (und zum besseren Verständnis) sind Kommentare nicht nur im Programmcode unverzichtbar.

    Bei kurzen Regulären Ausdrücken kann man darauf sicher verzichten, aber wenn es umfangreicher wird ist es zu empfehlen.

    Die einfachste Form des Kommentars ist das Kommentar-Token. Syntax: (?#KOMMENTAR)

    Dieser kann an jeder Stelle des Pattern eingefügt werden. Sinnvoll ist ihn vor einem zu kommentierenden Patternelement zu platzieren.

    Bsp. zum Splitten eines Windows/UNC-Datei-Pfades in: Lw | Ordner[optional] | Datei-mit-Erweiterung | Dateiname | Erweiterung

    ^(?i)((?#drive)[a-z]:|\\\\[a-z0-9]+)\\((?#folder)[^\/:*?"<>|\r\n]*\\)?((?#file)((?#filename)[^\\\/:*?"<>|\r\n]+)\.((?#extension)\w+))$

    Noch bessere Übersicht erreicht man durch eine umfangreiche Kommentierung und das möglichst neben jedem Teilausdruck.

    Das ist möglich, wenn das Flag für "extended" gesetzt wird: (?x)

    Bedeutung des Flags:

    • Leerzeichen werden ignoriert, Pattern darf mehrzeilig dargestellt werden

    • "#" dient als Kommentarzeichen, es wird mit allem Text danach in der Zeile ignoriert

    • Soll "#" Bestandteil eines Pattern sein, muss es maskiert werden: "\#"

    So ließe sich das folgende Pattern (Kommentarblock, geschachtelt) dann lesbarer darstellen:

    (?mi)(^\h*#(?>cs|comments-start)\b(?sU:(?>(?R)|.)*)^\h*#(?>ce|comments-end)\b.*\R)

    Code
    (?xmi)                # Flags: extended, multiline, insensitiv
    (^\h*\#               # Zeilenanfang: evtl. horiz. Spaces, Hash
    (?>cs|comments-start) # Atomic group Kommentar Start (kein Capture/Backtracking, längste mgl. Teilzeichenfolge in der Gruppe)
    \b                    # Position an einer Wortgrenze
    (?sU:(?>(?R)|.)*)     # Flag: single line & ungreedy, Atomic group mit Wdhlg. ges. Pattern od. bel. Zeichen auch öfter
    ^\h*\#                # Zeilenanfang: evtl. horiz. Spaces, Hash
    (?>ce|comments-end)   # Atomic group Kommentar Ende
    \b                    # Ende Wortgrenze
    .*\R )                # bel. Zei. bel. oft, Unicode-Zeilenumbruch

    Für die Verwendung weisen wir das dann einer Variablen zu:

    Eine weitere Möglichkeit ist das Definieren von Pattern in einer benannten Capturing Group.

    So kann ich z.B. einen AutoIt-String, eingefasst in einfachen/doppelten Anführungszeichen definieren und damit suchen:

    Code
    (?x)(?(DEFINE)                     # Einleitung der Definition
        (?<String> "(?> [^"]+ | \" )*" # doppelt markierter String
                  |
                   '(?> [^']+ | \' )*  # einfach markierter String"
        )
    )                                  # Ende Definition
    (?&String)                         # Aufruf des Pattern