今天用Ruby寫了以下代碼並進行了測試:
#正則表達式
line = gets
if line =~ /Perl|Python/ #如果在字符串中匹配了模式,=~返回字符串中匹配模式的開始位置
puts "Scripting language mentioned: #{line}"
end
我認為/Perl|Python/的意思是匹配"Perl"或者匹配"Python",但是當字符串中既存在"Perl"又存在"Python"時結果如何呢?
我猜想Perl和Python誰在前面(指的是在待匹配字符串中的順序而非/Perl|Python/中的順序)就匹配誰,比如"PerlPython"就應當匹配Perl,"PythonPerl"就應當匹配Python。
測試結果如下:
#input: PythonPerl
#output: Scripting language mentioned: PythonPerl
#input: PerlPython
#output: Scripting language mentioned: PerlPython
#input: Perl455Python
#output: Scripting language mentioned: Perl455Python
難道既有Perl又有Python的時候會進行兩次匹配?!懷着疑問又進行了如下測試:
#input: Perl1
#output: Scripting language mentioned: Perl1
#input: 1Perl
#output: Scripting language mentioned: 1Perl
咦,這是怎么回事?仔細思考后發現了問題所在,代碼的第二行如下:
if line =~ /Perl|Python/ #如果在字符串中匹配了模式,=~返回字符串中匹配模式的開始位置
這就是我開始犯錯的地方,我認為如果匹配成功,那么ruby會將匹配的字符串返回給line,但實際上:
- 在我的這幾行代碼里,line的值從鍵盤讀取了什么就是什么,從未改變過(=是賦值,=~是判斷是否匹配)
- =~返回的是字符串中匹配模式的開始位置,並不是匹配的字符串,因此我這個例子無法測試Perl和Python都存在的情況是否兩個都匹配(實際上是只匹配一個,是或的關系)
- 表達式 line =~ /Perl|Python/ 的值才是 =~ 最終返回的值,要么是nil,要么是字符串中匹配模式的開始位置
測試代碼改版:
line = gets
if line =~ /Perl|Python/ #匹配Perl或者Python,兩者其中一個匹配成功即結束,否則匹配失敗
puts line =~ /Perl|Python/ #如果在字符串中發現了模式,=~返回(也即表達式line =~ /Perl|Python/的返回值)模式的開始位置
puts "Scripting language mentioned: #{line}"#line的值始終為鍵盤輸入的內容,從未改變過
end
#input: 1Perl
#output:
1
Scripting language mentioned: 1Perl
折騰了半天,以上代碼並不能測試我想要測試的內容,反而我對 =~ 的理解更加深入了,又或者說我真正明白了上面這段代碼的意思,也是不亦樂乎~