Ruby大部分的內置類型都和其它的編程語言很相似。主要有strings,integers,floats,arrays等等。然而,只有腳本語言,如Ruby,Perl,和awk等提供了內置表達式類型的支持。正則表達式盡管比較隱蔽,但卻是一個很強大的文本處理工具。
正則表達式是使用指定的模式匹配字符串的一種簡單的方法。在Ruby中,創建正則表達式的典型方式是把模式寫在兩個斜線之間/pattern/。
畢竟,Ruby就是Ruby,正則表達式也是對象,也能像對象般操作。
例如,你可以使用下面的正則表達式寫一個模式,它匹配一個字符串中包含有Perl或Python。
<!--more-->/Perl|Python/
在正斜線體內,是兩個我們要匹配的字符串,它們使用"|"分隔。這個管道符的意思是"左邊的或者右邊的",在這個模式中是Perl或者Python。
你還可以在模式中使用括號,就像是在算術表達式中使用的那樣,因此這個模式還可以寫成
/P(erl|ython)/
你還可以在模式中指定重復。例如加號,/ab+c/匹配字符串中一個a后面有一個或多個b然后跟著是一個c。把加號換成星號,/ab*c/創建的正則表達式是匹配一個a后面跟著0個或多個b然后跟著是一個c。
你還可以在模式中匹配一組字符。常用的字符類型例子有/s,它匹配一個空白字符(space,tab,換行符,等等);/d匹配任意數字;/w匹配任意的典型單詞字符。句號(.)匹配(基本上)任意字符。
我們把所有這些組合起來,做成實用的正則表達式。
//d/d:/d/d:/d/d/ # a time such as 12:34:56/Perl.*Python/ # Perl, zero or more other chars, then Python/Perl Python/ # Perl, a space, and Python/Perl *Python/ # Perl, zero or more spaces, and Python/Perl +Python/ # Perl, one or more spaces, and Python/Perl/s+Python/ # Perl, whitespace characters, then Python/Ruby (Perl|Python)/ # Ruby, a space, and either Perl or Python
一但創建了一個模式,不能使用它是件很郁悶的事情。匹配操作符=~用來對一個字符串進行正則表達式匹配。如果匹配成功,=~返回第一次匹配成功的位置,否則它返回nil。也就是說,你可以在if和while的條件聲明中使用正則表達式。例如下面的代碼片段,
如果字符串中包含有文本Perl或Python時,輸出一條信息。
puts "Scripting language mentioned: #{line}" if line =~ /Perl|Python/
你能使用Ruby替換所有出現有Perl和Python的地方。
line.gsub(/Perl|Python/, 'Ruby')
從iHower的Ruby on Rails實戰圣經中摘一個示例,用正則表達式抓取手機號碼:
phone = "139-1234-5678"if phone =~ /(/d{3})-(/d{4})-(/d{4})/ start_with = $1 mid_num = $2 end_as = $3end
一般規則(為正常顯示,都放在代碼塊內)
高級規則
正則表達式操作
String和RegExp均支持=~和match兩個查詢匹配方法:
puts "I can say my name" =~ /name/ #-> 13a = /name/.match("I can say my name, my name I can say") #-> a is MatchDataputs a[0] #-> name
可以看出,如果能夠匹配,=~返回匹配的字符串位置,而match返回一個MatchData對象。如果不匹配,則返回nil。MatchData可以取出其中符合各個子匹配(或子模式)的內容,看下面的例子:
b1=/[A-Za-z]+,[A-Za-z]+,Mrs?/./.match("Jack,Wang,Mrs., nice person")puts b1[0] #-> Jack,Wang,Mrsb2=/(([A-Za-z]+),([A-Za-z]+)),Mrs?/./.match("Jack,Wang,Mrs., nice person:)puts b2[0] #-> Jack,Wang,Mrsputs b2[1] #-> Jack,Wangputs b2[2] #-> Jackputs b2[3] #-> Wang
m[0]返回匹配匹配主表達式的字符串,下面的方法是等同的:m[n]==m.captures[n]
Ruby也自動的為我們填寫一些全局變量,它們以數字做名,$1, $2, 等等,$1包含的是正則表達式中從左側開始的第一對小括號內的子模式所匹配的字符串,以此類推。我們看出匹配時,是從外到內,從左到右的順序。
貪婪量詞和不貪婪量詞
量詞*(表示零個或多個)和+(表示一個或多個)是貪婪的,它們會匹配盡可能多的字符,我們可以在*和+后面加一個?,使它成為非貪婪量詞:
下面代碼是: 1個或多個字符后接一個感嘆號。
teststr="abcd!efg!"match=/.+!/.match(teststr)puts match[0] #-> abcd!efg!limitmatch=/.+?!/.match(teststr)puts limitmatch[0] #-> abcd!
錨
錨是指必須滿座一定的條件,才能繼續匹配:
c=//b/w+/b/.match("!!Stephen**")puts c[0] #-> Stephen
前視斷言
前視斷言表示想要知道下一個指定的是什么,但并不匹配
肯定的前視斷言 (?=)
假設我們想要匹配一個數的序列,該序列以一個圓點結束,但并不想把圓點作為模式匹配的一部分
teststr="123 456 789. 012"m=//d+(?=/.)/.match(teststr)puts m[0] #-> 789
否定的前視斷言 (?!)
上例,如果//d+(?=/.)/改為//d+(?!/.)/,則puts m[0]輸出顯示為 123 。
修飾語
修飾語位于正則表達式最結束正則表達式的正斜杠的后面
1.i使正則表達式對大小寫不敏感
例如,/abc/i可以匹配Abc,abc,ABC等。
2.m使得正則表達式可以和任何字符匹配,包括換行符,通常情況下圓點通配符不匹配換行符。
字符串與正則表達式的相互轉換
字符串內插進正則表達式
teststr="a.c"re=/#{Regexp.escape(teststr)}/puts re.match("a.c")[0] #-> a.ctest=re.match("abc")puts test[0] #-> Nil
正則表達式轉換成字符串
puts /abc/.inspect #-> /abc/
使用正則表達式的常見方法:
例如,puts "test 1 2 and test 3 4".scan(//d/)會輸出["1","2","3","4"]。
新聞熱點
疑難解答
圖片精選