Font
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]8936[/thread]

RegEx-Frage: Was macht (?>[^\[\]]+)



<< >> 5 entries, 1 page
pktm
 2007-04-22 11:34
#76116 #76116
User since
2003-08-07
2921 articles
BenutzerIn
[Homepage]
user image
Hallo!

Was macht eigentlich das hier: (?>[^\[\]]+)

SOweit ich das ersehe sucht das nach einer Zeichenkette die aus mindestens einem Zeichen besteht, die aber keine [ oder ] beinhalten darf. Was aber macht (?>) ???

In der Doku steht dazu, dass das Backtracking verhindert und nur das genannte Muster matcht, mehr aber nicht.

SO ganz verstehe ich dasa aber nicht. Kann mir das jemand eventuell an einem Beispiel erklären? Losgelassen wurde das Ding auf solche Strukturen:
Code: (dl )
my $tree_aref = [['Root', ['Terminal', 'T2', ['Nonterminal', ['Terminal']]]]];


Grüße, pktm\n\n

<!--EDIT|pktm|1177227277-->
http://www.intergastro-service.de (mein erstes CMS :) )
PerlProfi
 2007-04-22 12:26
#76117 #76117
User since
2006-11-29
340 articles
BenutzerIn
[default_avatar]
Ist der reguläre Ausruck noch länger als das Stück ?
Wenn nicht macht es keinen Sinn.

Ein Ausdruck mit (?>) wird von der RegExp engine ausgeführt und ist nicht abhängig vom restlichen Teil des regulären Ausdrucks.
Das Beispiel aus perlretut ist da eigentlich ganz gut:
Code: (dl )
1
2
3
my $a = 'ab';
$a =~ /a*ab/; # matches
$a =~ /(?>a*)ab/; # doesn't match


MfG
pktm
 2007-04-22 13:08
#76118 #76118
User since
2003-08-07
2921 articles
BenutzerIn
[Homepage]
user image
Ja, die RegEx ist noch was länger:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    our $pat;
$pat = qr!
(?:
\[
(?>
(?>[^\[\]]+)
|
(??{$pat})
)*
\](?:\,\s)*
)
!x;

if( $s =~ /\[$x1\,\s?($pat)*\[\[?$x2/ ) {
return 1;
}else{
return 0;
}


Man kann damit nach unmittelbarer Dominanz in "geflatteten" Baum-Klammerstrukturen suchen.
http://www.intergastro-service.de (mein erstes CMS :) )
sid burn
 2007-04-23 16:54
#76119 #76119
User since
2006-03-29
1520 articles
BenutzerIn

user image
[quote=pktm,22.April.2007, 09:34]SOweit ich das ersehe sucht das nach einer Zeichenkette die aus mindestens einem Zeichen besteht, die aber keine [ oder ] beinhalten darf. Was aber macht (?>) ???

In der Doku steht dazu, dass das Backtracking verhindert und nur das genannte Muster matcht, mehr aber nicht.[/quote]
Mehr macht es auch nicht.
Durch (?> ... ) werden halt alle Backtracking Informationen sofort gelöscht.

Um es richtig zu Verstehen musst du Wissen wie eine Regex Engine Arbeitet. die Arbeitet zeichen für zeichen.

Wenn du z.B: s/.*h/ schreibst dann wird das erste Zeichen gematcht. Gleichzeitig wird eine Backtrack Information festgelegt, wenn die Regex nicht matchen sollte, dann kann ein Zeichen frei gegeben werden und der Rest der Regex wird neu evaluiert.

Den ein Sternchen bedeutet ja zwei Wege. Entweder beliebiges Zeichen nehmen, oder das zeichen weg lassen. Da es Greedy ist, wird immer erst ein Zeichen genommen. Da der Matcht der Regex selber aber wichtiger ist, kann vom ".*" immer ein Zeichen wieder freigegeben werden, und dann wird geschaut ob der Rest der Regex passt.

/.*h/ hat also zur folge das z.B. erst der ganze String von "hallo hubert" gematcht wird. Danach wird ein "h" erwartet. Das gibt es da aber nicht. Also kommt ein Backtrack und das ".*" gibt das letzte Zeichen frei. also matcht .* nun auf "hallo huber" dann wird das "t" mit dem "h" verglichen. Stimmt auch nicht also wird vom .* wird ein Backtrack gemacht u.s.w. bis die Regex matcht.


Die Klammern "(?> ... )" löschen alle Backtrackinformationen. Das heißt "(?>.*)h" wird niemals auf "hallo hubert" matchen. Das ".*" frisst sozusagen den ganzen String auf. Alle Backtracking Informationen sind gelöscht, es gibt also keinen weg mehr zurück. Das "h" matcht nicht am ende da es kein "h" dort existiert. Da keine Backtracking Informationen vorhanden sind, matcht die Regexe also nicht.


Wofür man sowas gebrauchen kann? Primär um deine Regexe Schneller zu machen, oder um die Regexe so zu verändern das sie genau das matcht was du auch möchtest.

Für weitere Informationen les dir das Buch Reguläre Ausdrücke aus dem O'Reilly Verlag durch. Super Buch, wo das alles genausten Erklärt wird. ;)
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
sid burn
 2007-04-23 17:03
#76120 #76120
User since
2006-03-29
1520 articles
BenutzerIn

user image
[quote=pktm,22.April.2007, 09:34]Was macht eigentlich das hier: (?>[^\[\]]+)[/quote]
Achso einmal schön geschrieben:

(?>
[^
\[\]
]+
)

Alle Backtracking Informationen werden gelöscht.
Eine Zeichenklasse die auf jedes Zeichen matcht was keine Eckigen klammern sind. Diese Zeichenklasse so oft wie möglich Matchen.

Durch das Löschen der Backtracking Informationen werden diese Zeichen auch nicht mehr freigegeben, egal was später noch für eine Bediengung kommt.

Dadurch läuft sie schneller, oder es ermöglicht erst wie gesagt das erkennen von richtig verschachtelten ausdrücken.
Nicht mehr aktiv. Bei Kontakt: ICQ: 404181669 E-Mail: perl@david-raab.de
<< >> 5 entries, 1 page



View all threads created 2007-04-22 11:34.