2012-09-05 17 views
8

Co oznaczają podwójne nawiasy kwadratowe w wyrażeniu regularnym? Jestem mylić o następujących przykładach:Jak używać podwójnych nawiasów w wyrażeniu regularnym?

/[[^abc]]/ 

/[^abc]/ 

ja testował użyciu Rubular, ale nie widzę żadnej różnicy pomiędzy jednym z podwójnymi uchwytami i pojedynczych nawiasach.

+0

stworzyłem [rozwiń-wsporniki] (https://www.npmjs.com/package/ expand-brackets), jeśli chcesz zobaczyć implementację JavaScript w dopasowaniu z klasami znaków posix – jonschlinkert

Odpowiedz

8

Posix character classes Użyj [:alpha:] notacja, które są używane wewnątrz wyrażenia regularnego jak:

/[[:alpha:][:digit:]]/ 

trzeba przewinąć w dół do sposobów, aby dostać się do informacji POSIX linku powyżej. Od dokumentów:

Wyrażenia nawiasów POSIX są również podobne do klas znaków. Stanowią przenośną alternatywę dla powyższego, z dodatkową korzyścią, że obejmują znaki spoza ASCII. Na przykład// d/dopasowuje tylko cyfry dziesiętne ASCII (0-9);// [[: cyfra:]]/dopasowuje dowolny znak w kategorii Unicode Nd.

/[[:alnum:]]/ - Alphabetic and numeric character 
/[[:alpha:]]/ - Alphabetic character 
/[[:blank:]]/ - Space or tab 
/[[:cntrl:]]/ - Control character 
/[[:digit:]]/ - Digit 
/[[:graph:]]/ - Non-blank character (excludes spaces, control characters, and similar) 
/[[:lower:]]/ - Lowercase alphabetical character 
/[[:print:]]/ - Like [:graph:], but includes the space character 
/[[:punct:]]/ - Punctuation character 
/[[:space:]]/ - Whitespace character ([:blank:], newline, 
carriage return, etc.) 
/[[:upper:]]/ - Uppercase alphabetical 
/[[:xdigit:]]/ - Digit allowed in a hexadecimal number (i.e., 0-9a-fA-F) 

Ruby obsługuje również następujące non POSIX klas postaci:

/[[:word:]]/ - A character in one of the following Unicode general categories Letter, Mark, Number, Connector_Punctuation 
/[[:ascii:]]/ - A character in the ASCII character set 
# U+06F2 is "EXTENDED ARABIC-INDIC DIGIT TWO" 

/[[:digit:]]/.match("\u06F2") #=> #<MatchData "\u{06F2}"> 
/[[:upper:]][[:lower:]]/.match("Hello") #=> #<MatchData "He"> 
/[[:xdigit:]][[:xdigit:]]/.match("A6") #=> #<MatchData "A6"> 
+0

Ta odpowiedź została dodana do [Często zadawanych błędów w przepełnieniu stosu] (http://stackoverflow.com/a/22944075/2736496) w części "Klasy postaci". – aliteralmind

4

"[" nie ma żadnego specjalnego znaczenia. [xyz] jest klasą znaków i będzie pasować do pojedynczego x, y lub z. Karat ^ przyjmuje wszystkie znaki nie w nawiasach.

Usunięcie ^ dla uproszczenia, widać, że pierwszy otwarty nawias jest dopasowywany do pierwszego nawiasu zamykającego, a drugi zamknięty nawias jest używany jako część klasy znaków. Ostatni nawias zamykający jest traktowany jako kolejny znak do dopasowania.

irb(main):032:0> /[[abc]]/ =~ "[a]" 
=> 1 
irb(main):033:0> /[[abc]]/ =~ "a]" 
=> 0 

ten wydaje się mieć taki sam wynik jak oryginał w niektórych przypadkach

irb(main):034:0> /[abc]/ =~ "a]" 
=> 0 
irb(main):034:0> /[abc]/ =~ "a" 
=> 0 

Ale to tylko dlatego, że wyrażenie regularne nie patrzy na dokładne dopasowanie.

irb(main):036:0> /^[abc]$/ =~ "a]" 
=> nil 
+1

Pamiętaj, że nie dotyczy to wszystkich smaków regex. Na przykład Java traktowałaby ją jako klasę znaków zawierającą tylko inną klasę znaków, więc '[[^ abc]]' i '[^ abc]' są efektywnie identyczne. –

+0

FWIW - Python zachowuje się równoznacznie z powyższą odpowiedzią, nie jest pewien innych języków ani tego, co "powinien" robić, chociaż wolę takie zachowanie, o którym wspomniałem @AlanMoore. – dfb