/ / Jaka jest różnica między () a [] w wyrażeniu regularnym? - regex

Jaka jest różnica między () i [] w wyrażeniu regularnym? - regex

Powiedzmy:

/(a|b)/ vs /[ab]/

Odpowiedzi:

19 dla odpowiedzi nr 1

W powyższym przykładzie nie ma dużej różnicy (w większości języków). Główną różnicą jest to, że () wersja tworzy grupę, do której można odwoływać się ponownie 1 w meczu (lub czasami $1). The [] wersja tego nie robi.

Również,

/(ab|cd)/  # matches "ab" or "cd"
/[abcd]/   # matches "a", "b", "c" or "d"

6 dla odpowiedzi nr 2

() w wyrażeniu regularnym służy do grupowania wyrażeń regularnych, umożliwiając zastosowanie operatorów do całego wyrażenia zamiast do pojedynczego znaku. Na przykład, jeśli mam wyrażenie regularne ab, następnie ab* odnosi się do a po którym następuje dowolna liczba bs (na przykład a, ab, abbitp.), podczas gdy (ab)* odnosi się do dowolnej liczby powtórzeń sekwencji ab (na przykład pusty ciąg, ab, ababitp.). W wielu silnikach wyrażeń regularnych () są również używane do tworzenia referencji, do których można się odwoływać po dopasowaniu. Na przykład w Ruby po wykonaniu "foo" =~ /f(o*)/, $1 będzie zawierać oo.

| w wyrażeniu regularnym wskazuje na przemian; oznacza wyrażenie przed taktem lub wyrażenie po nim. Możesz dopasować dowolną cyfrę do wyrażenia 0|1|2|3|4|5|6|7|8|9. Często zobaczysz zapakowane naprzemienniezestaw nawiasów w celu grupowania lub przechwytywania podwyrażenia, ale nie jest to wymagane. Możesz używać naprzemiennie również w przypadku dłuższych wyrażeń, takich jak foo|bar, aby wskazać albo foo lub bar.

Możesz wyrazić każde wyrażenie regularne (w sensie formalnym, teoretycznym, a nie rozszerzonym, z którego korzysta wiele języków), tylko z naprzemienną zmianą |, zamknięcie kleene *, konkatenacja (tylko napisanie dwóch wyrażeńobok siebie bez żadnych odstępów) oraz nawiasy do grupowania. Byłoby to jednak raczej niewygodne w przypadku skomplikowanych wyrażeń, dlatego powszechnie dostępnych jest kilka skrótów. Na przykład, x? jest tylko skrótem dla |x (to znaczy pusty ciąg znaków lub x), podczas y+ jest skrótem dla yy*.

[] są w zasadzie skrótem dla przemienności | wszystkich znaków lub zakresów znaków w nim zawartych. Tak jak powiedziałem, mógłbym pisać 0|1|3|4|5|6|7|8|9, ale o wiele wygodniej jest pisać [0-9]. Mogę też pisać [a-zA-Z] reprezentować dowolny list. Zauważ, że podczas [] zapewniają grupowanie, zasadniczo nie wprowadzają nowego odniesienia, do którego można będzie się później odwoływać; w tym celu musicie owinąć je w nawiasy ([a-zA-Z])

Zatem dwa przykładowe wyrażenia regularne są równoważne pod względem dopasowania, ale (a|b) ustawi pierwsze podpasowanie dla pasującego znaku, natomiast [ab] nie utworzy żadnych odniesień do pod-meczów.


5 dla odpowiedzi nr 3

Po pierwsze, gdy mówimy o wyrażeniach regularnych, to częstoważne, aby określić, o jakich wyrażeniach regularnych mówisz. Istnieje kilka odmian (takich jak tradycyjne wyrażenia regularne POSIX, wyrażenia regularne zgodne z Perl i Perl (PCRE) itp.).

Zakładając PCRE lub coś bardzo podobnego, co często jest obecnie najbardziej powszechne, istnieją trzy kluczowe różnice:

  1. Korzystając z grup w nawiasach, możesz sprawdzić opcje składające się z więcej niż jednego znaku. Więc / (a ​​| b) / może zamiast tego być / (abc | defg) /.
  2. Grupy w nawiasach wykonują operację przechwytywaniaabyś mógł wyodrębnić wynik (aby dopasować go do „b”, możesz odzyskać „b” i zobaczyć to). / [ab] / nie. Operację przechwytywania można zastąpić dodając?: Like so: / (?: a | b) /
  3. Nawet jeśli zastąpisz zachowanie przechwytywaniaw nawiasach podstawowa implementacja może być jeszcze szybsza w przypadku [] podczas sprawdzania pojedynczych znaków (chociaż nic nie mówi, że nie przechwytywanie (?: a | b) nie może być zoptymalizowane jako specjalny przypadek do [ab], ale kompilacja wyrażeń regularnych może potrwać nawet nieco dłużej).