Benutzer-Werkzeuge

Webseiten-Werkzeuge


regex

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
regex [2018-10-19 07:57:18] – [sed] manfredregex [2022-03-03 12:58:19] (aktuell) – [extended regular expressions (ERE)] manfred
Zeile 1: Zeile 1:
 +====== REGEX (REGular EXpression => Regulärer Ausdruck) ======
 +
 +  * **[[https://extendsclass.com/regex-tester.html]]** //bietet einen Online-Regex-Tester, der beim Testen und Debuggen von Regex hilft. Ein Regex-Visualizer ist integriert und hilft, reguläre Ausdrücke zu verstehen.//
 +  * **//[[https://www.regular-expressions.info/posix.html]]//**
 +  * **[[https://remram44.github.io/regex-cheatsheet/regex.html]]** - Gegenüberstellung verschiedener RegEx-Dialekte
 +  * **[[http://regexr.com/]]** - super Seite zum RegEx ausprobieren!!!
 +  * [[https://regex101.com/]] - RegEx online auf eigene Texte anwenden
 +  * [[http://mikiwiki.org/wiki/Regulärer_Ausdruck]]
 +  * [[https://en.wikipedia.org/wiki/Regular_expression]]
 +  * [[https://de.wikipedia.org/wiki/Regul%C3%A4rer_Ausdruck]]
 +  * [[http://www.lrz.de/services/schulung/unterlagen/regul/]]
 +  * **[[http://perldoc.perl.org/perlre.html]]**
 +  * **[[http://perldoc.perl.org/perlrequick.html]]**
 +
 +Die "Basic REGEX" sind recht einfach, allerdings fehlen ihnen einige wichtige Funktionen.
 +Deshalb wurden die REGEX zu den "Extended REGEX" erweitert.
 +Allerdings haben viele Softwarehersteller ihre eigenen erweiterten REGEX-Versionen veröffentlicht,
 +bevor die "Extended REGEX" veröffentlicht wurden.
 +Und so kam es, dass es zur Zeit viele verschiedene erweiterten REGEX-Versionen gibt,
 +die bekannteste ist die "Perl-REGEX"-Version, die meiner Meinung nach auch recht gut gelungen ist.
 +
 +  > echo -e "76556\n765567\n65567\n 65567\n 6556"
 +  76556
 +  765567
 +  65567
 +   65567
 +   6556
 +
 +
 +===== Grep =====
 +
 +  * ''grep'' -> versteht "__basic regular expressions (BRE)__" - //das ist der erste (unzureichende) RegEx-Implementation//
 +  * ''grep -F'' -> versteht __"keine" regular expressions__ - //wenn z.B. ein "." o.a. Zeichen nicht als RegEx interpretiert werden sollen//
 +  * ''grep -E'' -> versteht "__extended regular expressions (ERE)__" - //diese RegEx-Implementation versteht auch logische ODER-Verknüpfungen//
 +  * ''grep -P'' -> versteht "__Perl regular expressions (PCRE)__" - //die intuitivste RegEx-Implementation//
 +
 +
 +===== Reguläre Ausdrücke mit MySQL =====
 +
 +  * [[http://dev.mysql.com/doc/refman/5.1-olh/de/regexp.html]]
 +
 +
 +===== basic regular expressions (BRE) =====
 +
 +Das ist die grundlegende Version der POSIX-REGEX.
 +
 +[[https://www.arubanetworks.com/techdocs/ArubaOS_64_Web_Help/Content/ArubaFrameStyles/ESI/Basic_Regular_Expression.htm|Understanding Basic Regular Expression (BRE) Syntax]]
 +
 +Diese REGEX wird u.a. von "grep" bzw. "grep -G", "vi", "sed", "nl" und "more" unterstützt.
 +
 +Die //BRE// kennen keinen Platzhalter für ein Tabulatorzeichen,
 +stattdessen werden hier Leerzeichen erkannt!
 +
 +__genau eine Ziffer:__
 +  [0-9]
 +
 +__genau ein Zeichen, das keine Ziffer ist:__
 +  [^0-9]
 +
 +__Zeilenanfang:__
 +  ^
 +
 +__Zeilenende:__
 +  $
 +
 +__genau ein beliebiges Zeichen:__
 +  .
 +
 +__ein oder mehrere beliebige Zeichen:__
 +  .+
 +
 +__kein, ein oder mehrere beliebige Zeichen:__
 +  .*
 +
 +__genau ein Punkt:__
 +  [.]
 +
 +__mindestens ein Punkt:__
 +  [.]+
 +
 +__ein oder kein Punkt:__
 +  [.]*
 +
 +__genau ein Leerzeichen:__
 +  [ ]
 +
 +__mindestens ein Leerzeichen:__
 +  [ ]+
 +
 +__ein oder kein Leerzeichen:__
 +  [ ]*
 +
 +__genau einmal irgendein Zeichen, nur kein "/":__
 +  [^/]
 +
 +__mindestens einmal irgendein Zeichen, nur kein "/":__
 +  [^/]+
 +
 +__ein oder keinmal irgendein Zeichen, nur kein "/":__
 +  [^/]*
 +
 +__m-fache Wiederholung von "x":__
 +  [x]\{m\}
 +
 +__m..n-fache Wiederholung von "x":__
 +  [x]\{m,n\}
 +
 +__m..?-fache Wiederholung von "x":__
 +  [x]\{m,\}
 +
 +wenn nur die Zahl ''6556'', mit einer zusätzlichen Ziffer auf der rechten Seite und auf der linken Seite keinesfalls eine Ziffer stehen soll, ausgegeben werden soll:
 +  > echo -e "76556\n765567\n65567\n 65567\n 6556" | grep '[^0-9]6556[0-9]'
 +   65567
 +
 +
 +===== Perl regular expressions (PCRE) =====
 +
 +Das ist die von Perl erweiterte REGEX-Version, meiner Meinung nach, die beste!
 +
 +Diese REGEX wird u.a. von "grep -P" unterstützt.
 +
 +In manchen Anwendungsprogrammen, die mit regulären Ausdrücke umgehen, lässt sich die "[[http://www.lrz.de/services/schulung/unterlagen/regul/#greed|Gier]]" (engl. greed) regeln, mit der Zeichen von einem Wiederholungsoperator, also einem Stern oder einem Pluszeichen, "verschlungen" werden. Und zwar arbeiten diese Operatoren normalerweise mit maximaler Gier, können aber gezähmt werden, indem man ihnen ein Fragezeichen anhängt.
 +
 +__Beispiel zur "Gier": als Zeichenkette wird "Hello World" verwendet__
 +  l.+o    ->    llo Wo
 +  l.+?o   ->    llo
 +  l.*o    ->    llo Wo
 +  l.*?o   ->    llo
 +
 +__kein oder ein beliebiges Zeichen:__
 +  .?
 +
 +__genau ein Buchstabe oder eine Ziffer:__
 +  [0-9A-Za-z]
 +
 +__genau ein Buchstabe:__
 +  [a-zA-Z]
 +
 +__genau ein kleiner Buchstabe:__
 +  [a-z]
 +
 +__genau ein großer Buchstabe:__
 +  [A-Z]
 +
 +__genau eine Ziffer:__
 +  [0-9]
 +  [\d]
 +
 +__genau ein Zeichen, das keine Ziffer ist:__
 +  [^0-9]
 +  [^\d]
 +  [\D]
 +
 +__genau ein Punkt, Komma oder Semikolon:__
 +  [.,;]
 +
 +__genau ein Leerzeichen oder Tabulatorzeichen:__
 +  [ \t]
 +
 +__genau ein Leerzeichen:__
 +  [ ]
 +
 +__ein Tabulatorzeichen:__
 +  \t
 +
 +__ein Zeilenumbruch im Unix-Format:__
 +  \n
 +
 +__ein Wagenrücklauf (^M) => ein Zeilenumbruch im Mac-Format:__
 +  \r
 +
 +__ein Zeilenumbruch im Windows-Format:__
 +  [\r\n]
 +
 +__logische Verknüpfung "oder":__
 +  |
 +
 +__Gruppierung:__
 +  (...)
 +
 +__ein Piepston:__
 +  \a
 +
 +__ein Seitenvorschub:__
 +  \f
 +
 +__ein vertikaler Tabulator:__
 +  \v
 +
 +__Wortanfang bzw. Wortende:__
 +  \b
 +
 +__alles, nur kein Wortanfang bzw. Wortende:__
 +  \B
 +
 +__ein Buchstabe, eine Ziffer oder der Unterstrich:__
 +  \w
 +
 +__ein Zeichen, das weder Buchstabe noch Ziffer oder Unterstrich ist:__
 +  [\W]
 +  [^\w]
 +
 +__ein Leerzeichen und die Klasse der Steuerzeichen:__
 +  [\s]
 +  [\f\n\r\t\v]
 +
 +__ein Zeichen, das kein Whitespace ist:__
 +  [\S]
 +  [^\s]
 +
 +wenn nur die Zahl ''6556'', mit einer zusätzlichen Ziffer auf der rechten Seite und auf der linken Seite keinesfalls eine Ziffer stehen soll, ausgegeben werden soll:
 +  > echo -e "76556\n765567\n65567\n 65567\n 6556" | grep -P '[\D]6556[\d]'
 +   65567
 +
 +
 +===== extended regular expressions (ERE) =====
 +
 +Das ist die erweiterte Version der POSIX-REGEX.
 +
 +Diese REGEX wird u.a. von "egrep" bzw. "grep -E", "awk" und "Perl" unterstützt.
 +
 +Die //BRE// kennen keinen Platzhalter für ein Tabulatorzeichen,
 +stattdessen werden hier Leerzeichen erkannt!
 +
 +__genau ein Buchstabe oder eine Ziffer:__
 +  [[:alnum:]]
 +
 +__genau ein Buchstabe:__
 +  [[:alpha:]]
 +
 +__genau ein kleiner Buchstabe:__
 +  [[:lower:]]
 +
 +__genau ein großer Buchstabe:__
 +  [[:upper:]]
 +
 +__genau eine Ziffer:__
 +  [[:digit:]]
 +
 +__genau ein Zeichen, das keine Ziffer ist:__
 +  [^[:digit:]]
 +
 +__genau ein Hexadezimalziffer:__
 +  [[:xdigit:]]
 +
 +__genau ein sichtbares Zeichen:__
 +  [[:graph:]]
 +
 +__genau ein druckbares Zeichen:__
 +  [[:print:]]
 +
 +__genau ein Punkt, Komma oder Semikolon:__
 +  [[:punct:]]
 +
 +__genau ein horizontaler und vertikaler Tabulator, Zeilen- und Seitenvorschub, Wagenrücklauf oder Leerzeichen (Whitespace)__
 +  [[:space:]]
 +
 +__genau ein Leerzeichen oder Tabulatorzeichen:__
 +  [[:blank:]]
 +
 +__genau ein Steuerzeichen:__
 +  [[:cntrl:]]
 +
 +__m-fache Wiederholung von "x":__
 +  [x]{m}
 +
 +__m..n-fache Wiederholung von "x":__
 +  [x]{m,n}
 +
 +__m..?-fache Wiederholung von "x":__
 +  [x]{m,}
 +
 +wenn nur die Zahl ''6556'', mit einer zusätzlichen Ziffer auf der rechten Seite und auf der linken Seite keinesfalls eine Ziffer stehen soll, ausgegeben werden soll:
 +  > echo -e "76556\n765567\n65567\n 65567\n 6556" | grep -E '[^[:digit:]]6556[[:digit:]]'
 +   65567
 +
 +
 +===== sed =====
 +
 +  * [[http://www.unixguide.net/unix/sedoneliner.shtml]]
 +
 +Leider verwendet ''sed'' noch eine andere REGEX-Form,
 +hier ein paar Besonderheiten:
 +
 +__genau ein beliebiges Zeichen:__
 +  .
 +
 +__mindestens ein beliebiges Zeichen:__
 +  .\+
 +
 +__ein oder kein beliebiges Zeichen:__
 +  .*
 +
 +__genau ein Punkt:__
 +  [.]
 +
 +__mindestens ein Punkt:__
 +  [.]\+
 +
 +__ein oder kein Punkt:__
 +  [.]*
 +
 +__genau ein Leerzeichen oder Tabulator (white space):__
 +  [ \t]
 +
 +__mindestens ein Leerzeichen oder Tabulator (white space):__
 +  [ \t]\+
 +
 +__ein oder kein Leerzeichen oder Tabulator (white space):__
 +  [ \t]*
 +
 +__kein Leerzeichen oder Tabulator (white space) am Zeilenanfang:__
 +  ^\s\+
 +
 +__kein "/" am Zeilenanfang:__
 +  ^[^/]\+
 +
 +__alles, außer Bindestrich, Unterstrich, Punkt, kleine Buchstaben, große Buchstaben, Zahlen und das Plus:__
 +  [^-+_.a-zA-Z0-9]
 +
 +**Hierbei ist zu beachten, dass der Bindestrich als erstes und das Plus als zweites Zeichen angegeben werden!** Wird das Plus als letztes angegeben, dann muss es maskiert werden. Der Bindestrich wird von SED als Parameter interpretiert, wenn er nicht als erstes aufgeführt wird.
 +
 +zum Beispiel kann man so Sonderzeichen aus Dateinamen gegen einen Unterstrich austauschen:
 +  > echo 'Unglaublich! Wenn das passieren würde, bestünde kein Funken Hoffnung mehr_-+ .#zukrassalter.txt' | sed 's/[^-+_.a-zA-Z0-9]/_/g'
 +  Unglaublich__Wenn_das_passieren_wÃ_rde__bestÃ_nde_kein_Funken_Hoffnung mehr_-+_._zukrassalter.txt
 +
 +__Bitte beachtet, dass das "[[https://de.wikipedia.org/wiki/%C3%83|Ã]] auch ein gültiger Buchstabe aus dem lateinischen Schriftsystem ist und somit von diesem RegEx nicht ausgetauscht wird!__ Diese "tolle" Zeichenverunstaltung ist dadurch entstanden, dass ein Umlaut aus einem 16-Bit-Zeichensatz als zwei 8-Bit-Zeichen angezeigt wurde.
 +
 +16-Bit-Zeichensätze sind im internationalen Standard [[https://de.wikipedia.org/wiki/Unicode|Unicode]] festgelegt.
 +Unicode enthälten u.a. die Kodierungen [[https://de.wikipedia.org/wiki/UTF-8|UTF-8]], die u.a. in Linux, für E-Mail und für WWW verwendet werden sowie die Kodierungen [[https://de.wikipedia.org/wiki/UTF-16|UTF-16]], die bei Windows, Mac OS X, Java und .NET verwendet werden.
 +
 +8-Bit-Zeichensätze sind im internationalen Standard [[https://de.wikipedia.org/wiki/American_Standard_Code_for_Information_Interchange|ASCII]] festgelegt und enthalten die Kodierungen der [[https://de.wikipedia.org/wiki/ISO_8859|ISO 8859]]-Familie. Diese werden mehr und mehr durch Unicode-Zeichensätze abgelöst, werden aber in älteren Systemen (z.B. DOS und älteren Linux-Distributionen) weiterhin verwendet.
 +
 +
 +===== Perl Compatible Regular Expressions (PCRE) =====
 +
 +  * [[http://www.lehrer.uni-karlsruhe.de/~za186/perl/perl01.htm]]
 +  * [[http://doc-tcpip.org/Unix/reg.exp.html]]
 +  * [[http://de.selfhtml.org/perl/sprache/operatoren.htm]]
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2toc.html]]
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2g.html]]
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2i.html]]
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2l.html]]
 +
 +hier ein Beispiel für ein Match:
 +
 +kein Match
 +  # perl -0ne 'print "$ARGV\n" if m/Nameserver/' /etc/resolv.conf
 +
 +ein Match
 +  # perl -0ne 'print "$ARGV\n" if m/nameserver/' /etc/resolv.conf
 +  /etc/resolv.conf
 +
 +
 +hier ein Beispiel für ein UND-verknüpften Match:
 +
 +kein Match
 +  # perl -0ne 'print "$ARGV\n" if m/nameserver/ && m/10.10.2.20/' /etc/resolv.conf
 +
 +ein Match
 +  # perl -0ne 'print "$ARGV\n" if m/nameserver/ && m/10.10.2.10/' /etc/resolv.conf
 +/etc/resolv.conf
 +
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2d.html]]
 +
 +In Perl werden reguläre Ausdrücke auf mannigfache Weise benutzt. Die einfachste Möglichkeit ist, zu prüfen, ob der Text in einer bestimmten Variablen auf einen regulären Ausdruck paßt. Das folgende Programmstück prüft den String in der Variable $reply und gibt aus, ob darin nur Ziffern vorkommen:
 +  #!/usr/local/bin/perl -w
 +  
 +  $var = "0123456789";
 +  
 +  if ( $var =~ m/^[0-9]+$/ )
 +  {
 +          print "$var sind alles nur Ziffern\n";
 +  } else
 +  {
 +          print "$var sind nicht nur Ziffern\n";
 +  }
 +
 +Soll nicht nur der erste Treffer modifiziert werden, dann muss am Ende der REGEX ein "g" für global angehängt werden: ''"m/^[0-9]+$/"'' wird zu ''"m/^[0-9]+$/g"''
 +
 +  * [[http://www.oreilly.de/catalog/regexger/chapter/kap-2i.html]]
 +
 +Wenn die Regex wahr ist, dann wird der Teil des Strings in $var, der auf den regulären Ausdruck gepaßt hat, durch Ersatz ersetzt.
 +  #!/usr/local/bin/perl -w
 +  
 +  $var = "Jeff";
 +  
 +  if ( $var =~ s/Jeff/Jeffrey/ )
 +  {
 +          print "$var wurde ersätzt\n";
 +  } else
 +  {
 +          print "$var wurde nicht ersätzt\n";
 +  }
 +
 +Soll nicht zwischen Groß- und Kleinschreibung unterschieden werden, dann muss man am Ende der REGEX ein "i" hängen: ''"s/Jeff/Jeffrey/"'' wird zu ''"s/Jeff/Jeffrey/i"''
 +
 +
 +==== Parameter bzw. Argumente übergeben ====
 +
 +Will man auf der Kommandozeile Parameter übergeben, dann wird das erste im Perl-Script z.B. mit **''$var = "$ARGV[0]";''** in der Variable ''$var'' abgelegt.
 +
 +
 +===== Oniguruma regular expressions =====
 +
 +  * [[http://en.wikipedia.org/wiki/Oniguruma]]
 +
 +Bisher war //PCRE// die am weitesten verbreitete RegEx-Variante,
 +mittlerweile gewinnt aber eine neue Version immer mehr an Popularität: Oniguruma
 +
 +Oniguruma ist ist eine RegEx-Bibliothek, die unter der BSD-Lizenz steht,
 +sie unterstützt ein sehr großes Spektrum an Zeichensätzen, darunter auch UTF-8.
 +
 +Sie wird in der Interpretersprache Ruby seit der Version 1.9 eingesetzt und in der
 +Interpretersprache PHP5.
 +Seit der Version 7.7 verwendet sogar //PCRE// ein Oniguruma-Konstrukt für Subroutinen.
 +
 +Es wird ebenso in Produkten wie //Tera Term//, //TextMate// und //SubEthaEdit// eingesetzt.
 +
 +
 +===== problematische Sonderfälle, die mir aufgefallen sind =====
 +
 +Es bestand das Problem, dass in einem Skript überprüft werden muss, ob eine Zeichenkette numerisch ist oder ggf. Buchstaben enthält.
 +
 +Leider funktioniert mit "''test''" ("''[''") das nicht direkt (siehe "''man test''").
 +Also habe ich gedacht, eine negierende RegEx könnte helfen.
 +Wenn also nur Zeichen durchgelassen werden, die nicht //nicht-numerisch// sind.
 +
 +Als Testobjekte sollen diese Zeichenketten dienen:
 +  - ''123''
 +  - ''ABC''
 +  - ''Def''
 +  - ''ghi''
 +  - ''1a''
 +  - ''a1''
 +
 +hiervon darf nur die erste (''123'') durchgehen.
 +
 +
 +mit //Pearl-RegEx// würde ich das so formulieren
 +  > echo -e "123\nABC\nDef\nghi\n1a\na1" | grep -P ''[^a-zA-Z]''
 +  123
 +  1a
 +  a1
 +
 +oder mit //extended regular expressions// so:
 +  > echo -e "123\nABC\nDef\nghi\n1a\na1" | grep -E '[^[:alpha:]]'
 +  123
 +  1a
 +  a1
 +
 +Leider funktioniert keine von beiden richtig! :-(
 +
 +nur diese RegEx funktioniert richtig (Quelle: [[https://forum.ubuntuusers.de/topic/eingabe-auf-zahlen-und-buchstaben-pruefen/#post-2869188|Post von riffraff im Forum von ubuntuusers.de]]):
 +  > for A in 123 ABC Def ghi 1a a1 ; do if [[ "${A}" == "?(+|-)+([0-9])" ]] ; then echo "${A}" ; fi ; done
 +  123
 +