Leser: 23
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
#!/usr/bin/perl use strict; use warnings; my $string =<<"HERE"; I have some <brackets in <nested brackets> > and <another group <nested once <nested twice> > > and that's it. HERE my @groups = $string =~ m/(<(?:[^<>]++|(?1))*>)/g; $" = "\n\t"; print "Found:\n\t@groups\n";
QuoteBei beiden Beispielen bekomme ich mit (wie es geschrieben steht) und ohne dem "possesive +" das gleiche ausgegeben. Wird das possesive + gesetzt, damit es schneller geht?
1
2
3
4
my $str = 'abcdefgha';
print $str =~ m/\A\w+a/ ? "MATCHED\n" : "NO MATCH\n";
print $str =~ m/\A\w++a/ ? "MATCHED\n" : "NO MATCH\n";
Quoteder erste Versuch kommt bis "I have some <brackets in "
auch wenn es keine Treffer war, kommt "brackets in " in den ersten capture puffer
da es kein Treffer war geht es weiter zum "oder"
mit dem "(?1)" wird jetzt nach "brackets in " gesucht und gefunden
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
m/
( # Speichere alles in $1
< # Suche nach einem Literalen "<"
(?: # Entweder...
[^<>]++ # Soviele nicht "<" und ">" wie möglich einfangen"...
| # oder...
(?1) # wenn man hier ist muss das nächste zeichen ein "<"
# oder ">" sein. Mit (?1) wird die Regex Engine angewiesen
# weiter bei der erste klammern "(" weiterzumachen.
# kurz gesagt immer wenn du auf "<" oder ">" stößt
# ruft sich die regex praktisch "rekursiv" immer wieder
# selber auf. Dadurch kann eine beliebige
# verschachtelungstiefe erreicht werden.
# Wenn die Regex bei der ersten Klammer weiter macht muss
# wieder ein "<" kommen, kommt das nicht vorher
# (wenn es ein ">" ist )
# dann fährt die regex nun an dieser stelle weiter
)*
> # und hier wird nun das ">" erkannt das von (&1) nicht
# erkannt wurde
)
/xg;