?
This document uses PHP Chinese website manual Release
下面就來講講ruby支持的正則表達式符號(元字符)。
有這么個規(guī)則:
下文中出現(xiàn)的“匹配多字節(jié)字符的正則表達式”是指,通過使用$KCODE進行設(shè)定,或顯式地使用漢字選項(請參考正則表達式字面值)等方式進行的匹配多字節(jié)字符的正則表達式。
^
行首。與字符串的頭部或換行符之后的位置相匹配。
$
行尾。與字符串的尾部或換行符之前的位置相匹配。不包括換行符本身。
ruby 1.8 特性:以前,只匹配字符串尾部換行符前的位置,現(xiàn)在則擴大到字符串的尾部。trap::Regexp
p "\n".gsub(/$/, "o") => "o\n" (1.6) => "o\no" (1.8)
.
匹配除換行符以外的任意一個字符。使用正則表達式選項 m(多行模式。請參考正則表達式字面值) 時,則匹配包括換行符在內(nèi)的任意一個字符。在匹配多字節(jié)字符的正則表達式中,則匹配一個字(非單字節(jié))。
當遇到不完整的多字節(jié)字符的一部分(無法判斷該字符是多字節(jié)字符?二進制?還是ASCII)時,也不會匹配。
p /./e =~ "あ"[0,1] # => nil
\w
字母和數(shù)字。等同于[0-9A-Za-z]
。
若為匹配多字節(jié)字符的正則表達式時,則也會匹配日語的全角字符。
\W
非字母和數(shù)字。\w
以外的單個字符。
\s
空字符。相當于[ \t\n\r\f]
\S
非空字符。[ \t\n\r\f]
以外的單個字符。
\d
數(shù)字。即[0-9]
\D
非數(shù)字
\A
字符串頭部。與^
不同的是,它不受有無換行符的影響 。
\Z
字符串尾部。若字符串以換行符結(jié)尾,則匹配換行符前的位置。
ruby 1.8 特性:以前,只匹配字符串尾部換行符前的位置,現(xiàn)在則擴大到字符串的尾部。trap::Regexp
p "\n".gsub(/\Z/, "o") => "o\n" (1.6) => "o\no" (1.8)
\z
字符串結(jié)尾。與$以及\Z不同的是,它不受有無換行符的影響。
\b
在字符范圍描述符之外時表示詞邊界(匹配從\w到\W)。在字符范圍描述符之內(nèi)時表示退格符(0x08)。
\B
非詞邊界
\G
在上次成功匹配的地方(之后)進行匹配(不留余地)。只有在首次使用時才會匹配到頭部(與\A相同)。
可以用在scan和gsub中。當您想在上次匹配的地方之后再進行匹配的話,可以使用。
舉個簡單(沒什么用)的例子。
# 從頭取出3位數(shù)字(數(shù)字必須相連)。 str = "123456 789" str.scan(/\G\d\d\d/) {|m| p m }
[ ]
指定字符范圍。請參考字符范圍
。*
前面元素至少出現(xiàn)0次。盡可能匹配較長的部分。
*?
負責指定數(shù)量(quantifiers)。表示前面元素至少出現(xiàn)0次(盡量匹配短的部分)
+
負責指定數(shù)量(quantifiers)。表示前面元素至少出現(xiàn)1次
+?
負責指定數(shù)量(quantifiers)。表示前面元素至少出現(xiàn)1次(盡量匹配短的部分)
{m}
{m,}
{m,n}
指定元素重復出現(xiàn)的次數(shù)(interval quantifier)。分別表示前面元素重復出現(xiàn)
{,n}
或 {,}
將導致匹配失敗。
str = "foofoofoo" p str[/(foo){1}/] # => "foo" p str[/(foo){2,}/] # => "foofoofoo" p str[/(foo){1,2}/] # => "foofoo"
正則表達式 ?
, *
, +
分別等同于 {0,1}
, {0,}
{1,}
。
{m}?
{m,}?
{m,n}?
指定元素重復出現(xiàn)的次數(shù)(interval quantifier)。分別表示前面元素重復出現(xiàn)
(盡量匹配短的部分)。
?
負責指定數(shù)量(quantifiers)。表示前面元素至多出現(xiàn)1次。
??
負責指定數(shù)量(quantifiers)。表示前面元素至多出現(xiàn)1次(盡量匹配短的部分)
|
選擇(alternative)。
( )
正則表達式的群組化。與括號中的正則表達式相匹配的字符串將被保存下來,供后方參考使用。
\1
, \2
... \n
后方參考(back reference)。請參考后方參考。
(?# )
注釋。括號中的任意字符串將被忽視。
(?: )
不具備后方參考功能的群組化。它不為\1,\2(或$1,$2)提供服務(wù),是一種單純的群組功能。
/(abc)/ =~ "abc" p $1 => "abc" /(?:abc)/ =~ "abc" p $1 => nil
(?= )
先行(lookahead)。使用模式(pattern)指定位置(不留間隔)
(?=re1)re2
表示將匹配同時符合re1和re2的要求的字符串。
re1(?=re2)
という山附は、稿に re2 とマッチする矢機誤が魯く、正則表達式 re1 です。
p /foo(?=bar)/ =~ "foobar" # => 0 p $& # => "foo" (bar の嬸尸の攫鼠はない)
(?! )
否定先行(negative lookahead)。使用否定的模式(pattern)來指定位置(不留間隔)
(?!re1)re2
該正則表達式表示,匹配re1但不匹配re2。
# 除000以外的3位數(shù)字 re = /(?!000)\d\d\d/ p re =~ "000" # => nil p re =~ "012" # => 0 p re =~ "123" # => 0 # C語言標識符 (首位是[A-Za-z_]然后是[0-9A-Za-z_]的字符串) /\b(?![0-9])\w+\b/
(?> )
禁用回縮功能。
該功能尚處于試驗階段。將來有可能被停用,請您注意使用。特別是不要在廣義庫中使用。
(?ixm-ixm)
正則表達式中的i選項、x選項、m選項的開關(guān)。請您參考正則表達式字面值來了解選項的詳細內(nèi)容。
re = /A(?i)a(?-i)A/ p re =~ "AaA" # => 0 p re =~ "AAA" # => 0 p re =~ "AAa" # => nil
(?ixm-ixm: )
括號中的i選項、x選項、m選項的開關(guān)。在括號范圍內(nèi)有效。
re = /A(?i:a)A/ p re =~ "AaA" # => 0 p re =~ "AAA" # => 0 p re =~ "AAa" # => nil
正則表達式 \1 \2 ... \n 表示后方參考。\n表示將匹配第n個括號(正則表達式的()表示群)的內(nèi)容保存起來,供后面使用。
/((foo)bar)\1\2/
和
/((foo)bar)foobarfoo/
是一樣的。
例:
re = /(foo|bar|baz)\1/ p re =~ 'foofoo' # => 0 p re =~ 'barbar' # => 0 p re =~ 'bazbaz' # => 0 p re =~ 'foobar' # => nil
對應(yīng)的括號必須位于后方參考表達式的左側(cè)。
若后方參考表達式位于對應(yīng)的括號中時,匹配常常會失敗。當后方參考表達式中的數(shù)字是1位,且沒有對應(yīng)的括號時,匹配也將失敗。
p /(\1)/ =~ "foofoofoo" # => nil p /(foo)\2/ =~ "foo\2" # => nil
雖然可以指定2位以上的后方參考表達式,但是不要把它同反斜線表示法的\nnn(對應(yīng)于8進制數(shù)nnn的字符)混為一談。當數(shù)字只有1位時,通常是后方參考表達式。當指定了一個超過2位的數(shù)字時,若沒有對應(yīng)括號的話,則被看作是8進制代碼。
相反地,若在正則表達式中使用1位的8進制代碼時,必須以0打頭,例如\01等(不可能存在形如\0這樣的后方參考表達式,因此不會混淆)。
p /\1/ =~ "\1" # => nil # 無對應(yīng)括號的后方參考 p /\01/ =~ "\1" # => 0 8 進制代碼 p /\11/ =~ "\11" # => 0 8 進制代碼 # 8 進制代碼 (因為沒有對應(yīng)括號) p /(.)\10/ =~ "1\10" # => 0 # 后方參考 (因為有對應(yīng)的括號) p /((((((((((.))))))))))\10/ =~ "aa" # => 0 # 8 進制代碼 (因為沒有像"\0" + "8" -> \08 這樣的8進制代碼) p /(.)\08/ =~ "1\0008" # => 0 # 如果想在后方參考表達式之后插入數(shù)字的話,就必須使用括號加以分隔。 p /(.)(\1)1/ =~ "111" # => 0
正則表達式 [] 負責指定字符范圍。這將匹配 [] 內(nèi)列出的任何一個字符。
例如/[abc]/表示只要匹配"a", "b", "c"中任何一個即可。也可以按照ASCII代碼順序,在連續(xù)的字符串之間插入“-”后寫成/[a-c]/也是一樣的效果。另外,若頭上是“^”的話,表示要匹配指定字符之外的一個字符。
若“^”不在頭上的話,表示匹配該字符本身。同時,當“-”出現(xiàn)在頭或尾上時,表示匹配該字符本身。
p /[a^]/ =~ "^" # => 0 p /[-a]/ =~ "-" # => 0 p /[a-]/ =~ "-" # => 0 p /[-]/ =~ "-" # => 0
空的字符范圍將引發(fā)錯誤。
p /[]/ =~ "" p /[^]/ =~ "^" # => invalid regular expression; empty character class: /[^]/
當“]”出現(xiàn)在頭上(或否定的“^”之后)時,表示“]”本身,而并非字符范圍的結(jié)尾。
p /[]]/ =~ "]" # => 0 p /[^]]/ =~ "]" # => nil
可以使用反斜線對"^", "-", "]" 以及 "\\"(反斜線)進行轉(zhuǎn)義,使其匹配該字符本身。
p /[\^]/ =~ "^" # => 0 p /[\-]/ =~ "-" # => 0 p /[\]]/ =~ "]" # => 0 p /[\\]/ =~ "\\" # => 0
在[]中可以使用反斜線表示法以及正則表達式\w, \W, \s, \S, \d, \D (這些都是表示字符范圍的簡寫法)。
請注意,下列包含否定意味的字符范圍也將匹配換行符(正則表達式 \W,\D 也是如此)。
p /[^a-z]/ =~ "\n" # => 0
字符范圍中也可以使用下列特殊的表達法,但是,將來這些表達法是否會繼續(xù)得到支持還未可知(所以此處從略,欲知詳情請參考grep(1)的手冊)。
[:alnum:] 數(shù)字和字母 0-9a-zA-Z [:alpha:] 字母 a-zA-Z [:blank:] 空白類 [:cntrl:] 控制字符 [:digit:] 數(shù)字 [:graph:] 除空白以外的可打印可視字符 [:lower:] 小寫字母 [:print:] 可視字符 [:punct:] 符號 [:space:] 空白字符 [:upper:] 大寫字母 [:xdigit:] 16進制字符
例: (包括"[]"在內(nèi),"[:...:]"表示1個字符。并非文字類的"[]")
p /[[:alnum:]][[:cntrl:]]/ =~ "a\x01" # => 0
注: 全角字符不在考慮范圍之內(nèi)。即使指定讓正則表達式對漢字進行匹配時,[:alpha:]等也不會匹配全角的字母。
p /[[:alpha:]]/e =~ "A" # => nil
用特殊括號(?> )將正則表達式括起來后,與該正則表達式相匹配的字符串中的回縮功能就將失效。舉例如下。
例如在通常的正則表達式中
p /(a*)ab/ === 'aaab'
是匹配的。該匹配過程如下所示。
接下來的匹配都不成功,最終導致整體匹配失敗。
簡單說來,通常的正則表達式是“貪婪型的匹配”,而(?> )則是“超貪婪型的匹配”,因為它一旦匹配成功就決不放手。
為了便于您拷貝使用,我們將其代入到以$re_開頭的全局變量中。
浮點數(shù)(包括整數(shù))
$re_float = /[-+]?(?:[0-9]+(\.[0-9]*)?|(\.[0-9]+))([eE][-+]?[0-9]+)?/ p $re_float =~ "1.23" # => 0 p $&.to_f # => 1.23 p $re_float =~ ".23" # => 0 p $&.to_f # => 0.23 p $re_float =~ "1.23e1" # => 0 p $&.to_f # => 12.3 p $re_float =~ "1.23e-1" # => 0 p $&.to_f # => 0.123
方法1:使用回行和先行的方法(回行(lookbehind)需要Oniguruma庫的支持)
p "tone of 12345Hz".gsub(/(?<=\d)(?=(?:\d\d\d)+(?!\d))/, ',') => ruby 1.8.0 (2003-08-07) [i586-linux] "tone of 12,345Hz"
方法2:只使用先行的方法
p "tone of 12345Hz".gsub(/(\d)(?=(?:\d\d\d)+(?!\d))/, '\1,') => ruby 1.8.0 (2003-08-07) [i586-linux] "tone of 12,345Hz"
方法3:不使用先行的方法
s = "tone of 12345Hz" nil while s.gsub!(/(.*\d)(\d\d\d)/, '\1,\2') p s => ruby 1.8.0 (2003-08-07) [i586-linux] "tone of 12,345 Hz"