Ich versuche ein interessanteres Rätsel zu machen. Diesmal testen wir ob ein String mit einem anderern, Muster (Pattern) genannten String, übereinstimmt.
Der Nützlichkeit wegen, führen wir einige Zeichen ein, die in einem Muster eine spezielle Bedeutung besitzen. Die folgenden sind spezielle Zeichen.
[ ] Bereichsangabe. (z.B., [a-z] bedeutet: ein Buchstabe
von a bis z)
\w Buchstabe oder Zahl. Dasselbe wie [0-9A-Za-z_]
\W weder Buchstabe noch Zahl
\s Whitespace-Zeichen. Dasselbe wie [ \t\n\r\f]
\S nicht Whitespace-Zeichen.
\d Ziffer. Dasselbe wie [0-9].
\D keine Ziffer.
\b Wortgrenze (außerhalb von Bereichsangaben).
\B keine Wortgrenze.
\b Backspace (0x08) (innerhalb von Bereichsangaben)
* null oder mehrmalige Wiederholung des vorhergehenden Ausdrucks
+ ein oder mehrmalige Wiederholung des vorhergehenden Ausdrucks
{m,n} mindestens n-mal, aber nicht mehr als m Wiederholungen des vorhergehenden Ausdrucks
? mindestens null-mal, aber nicht mehr als eine Wiederholung des vorhergehenden Ausdrucks
| entweder vorhergehender oder folgender Ausdruck
( ) Gruppierung
Zum Beispiel bedeutet `^f[a-z]+' "Mindestens einmalige Wiederholung von Zeichen im Bereich von `a' bis `z', denen ein `f' vorausgeht. Spezielle Zeichen wie oben genannte, werden `regüläre Ausdrücke' genannt. Reguläre Ausdrücke sind nützlich zur Suche innerhalb von Strings, deshalb wird es sehr oft in der UNIX-Umgebung benutzt. Ein typisches Beispiel ist `grep'.
Um reguläre Ausdrücke zu verstehen, laßt uns ein kleines Programm schreiben.
Speichere das folgende Programm in eine Datei `regx.rb' und führe es aus.
Bemerke: Dieses Programm funktioniert nur unter UNIX, weil es bestimmte Video-Escape-Sequenzen benutzt.
st = "\033[7m"
en = "\033[m"
while TRUE
print "str> "
STDOUT.flush
str = gets
break if not str
str.chop!
print "pat> "
STDOUT.flush
re = gets
break if not re
re.chop!
str.gsub! re, "#{st}\\&#{en}"
print str, "\n"
end
print "\n"
Dieses Programm verlangt zwei Eingaben und zeigt Übereinstimmung der ersten Eingabe mit dem bei der zweiten Eingabe eingegebenen Muster durch invertieren der Farben (hier rot). Machen Sie sich nichts draus, wenn Sie Details noch nicht verstehen, sie werden später erklärt.
str> foobar pat> ^fo+ foobar ~~~
# foo ist invertiert und ``~~~'' ist nur für textbasierte Browser.
Lassen Sie uns mehrere Eingaben probieren.
str> abc012dbcd555
pat> \d
abc012dbcd555
~~~ ~~~
Dieses Programm erkennt mehrere Übereinstimmungen.
str> foozboozer pat> f.*z foozboozer ~~~~~~~~
`fooz' stimmt nicht überein, dafür aber `foozbooz', da ein regulärer Ausdruck immer den längsten passenden Teilstring auswählt.
Folgendes Muster ist zu schwierig um auf den ersten Blick zu erkennen.
str> Wed Feb 7 08:58:04 JST 1996
pat> [0-9]+:[0-9]+(:[0-9]+)?
Wed Feb 7 08:58:04 JST 1996
~~~~~~~~
In Ruby wird ein regulärer Audruck von einem `/' angeführt und beendet. Einige Methoden konvertieren einen String automatisch in einen regulären Ausdruck.
ruby> "abcdef" =~ /d/ 3 ruby> "abcdef" =~ "d" 3 ruby> "aaaaaa" =~ /d/ FALSE ruby> "aaaaaa" =~ "d" FALSE
`=~' ist der Übereinstimmungs-Operator, der bei regulären Ausdrücken verwendet wird. Er gibt die Position der Übereinstimmung zurück, andernfalls `false'.