2009-12-04 48 views
0

What regular expressions can never match?/$./作爲回答給出。我玩了一下,發現以下兩行代碼產生不同的輸出。第二場比賽,但第一場比賽沒有。誰能解釋爲什麼?

$ printf 'a\nb\n' | perl -0777 -ne 'print if m/$./m' 
$ perl -0777 -e '$_="a\nb\n"; print if m/$./m' 

此外,請注意,在下面的添加<>導致匹配失敗:

$ printf 'a\nb\n' | perl -0777 -e '$b = "a\nb\n"; say $b =~ m/$./m' 
$ printf 'a\nb\n' | perl -0777 -e '$b = "a\nb\n"; <>; say $b =~ m/$./m' 

(即,第一打印 '1' 時,第二打印一個空行)

回答

9

開啓警告給出了一個大概的原因線索:

 
$ printf 'a\nb\n' | perl -0777 -w -e 'use feature qw/say/; $b = "a\nb\n"; say $b =~ m/$./m' 
Use of uninitialized value $. in regexp compilation at -e line 1. 
1 

你使用正則表達式未定義的值。序列$. refers to the special variable for the line number of the last-accessed file handle。它指定正則表達式「線後跟任意字符的結束」。由於你沒有訪問任何文件,它仍然是undef,所以正則表達式是空的。當您使用-n選項,它有效地包裝程序中while (<>) { ... }休息,所以你讀<>並與$.1結束了,因爲你已經讀過一行。

當你說在第二次嘗試<>,您訪問過的標準輸入文件句柄。現在正則表達式是m/1/m,它與輸入字符串不匹配。

+1

你可以用'-E',而不是'-e'它做同樣的事情-e'use功能「:5.10'' =>' perl -0777 -wE'$ b =「a \ nb \ n」;說$ b =〜m /$./ m'' – 2009-12-04 18:11:15

+0

@Brad:感謝'-E'提示! – 2009-12-04 18:30:41

5

這段代碼給我打印了「破碎的管道」,因爲perl不希望有任何輸入。它還使用未定義的變量$.(如果您將-w切換到Perl,您會看到它)。該變量$.表示當前行號,然後通過<...>讀取行。這就是爲什麼在這個例子中未定義的真實:

## matching pattern will look like m//m 
printf 'a\nb\n' | perl -0777 -e '$b = "a\nb\n"; say $b =~ m/$./m' 

下面的代碼讀取管道數據,但不會匹配,因爲$.<>後成爲等於1。而匹配模式成爲m/1/m

## matching patter will be m/1/m, which is not found in $b value 
printf 'a\nb\n' | perl -0777 -e '$b = "a\nb\n"; <>; say $b =~ m/$./m' 

更新:

使用m'$.'mm/$ ./mx(感謝邁克爾·卡曼)禁止變量代換。

+0

當然!特殊變量'$ .'!那麼如何寫一個正則表達式呢?使用'm'$。''? – 2009-12-04 17:03:04

+0

@JB:「$」是的,'M'是一個好主意 – 2009-12-04 17:04:31

+0

''/\$./解析爲「文字‘$’後跟任意字符」您可以使用'/ x'改性劑將它們分開,雖然:'M/$/x' – 2009-12-04 17:21:20

0

在第一種情況下,我相信這是因爲-n開關。換句話說

printf 'a\nb\n' | perl -0777 -ne 'print if m/$./m' 

導致$ _通過循環來首次獲得的價值a\nb\n第二次這麼清楚將不匹配。而在第二個例子中使用/ m $匹配\ n,這就是匹配的原因。

與後兩者的例子,我還在上:)

編輯:哇,我有完全錯了,我想你可能也。問題是m/$./m而不是後面跟着一個通配符,而是變量$。插入爲正則表達式。哎呀!

6

在您的正則表達式中的$.被解析爲特殊變量$.$INPUT_LINE_NUMBER)的值,而不是「任何字符後跟隨任何字符的行尾」。

另請注意,/m修飾符將$的含義從字符串末尾的匹配更改爲匹配字符串中任何位置的行結束符。見perlre中的Modifiers。這意味着它可能有後的東西(用適當的修飾):

say "a\nb\n" =~ m/$ ./msx; 

打印「1」。 /x修飾符允許使用嵌入的空格,所以我們可以將$.分開,以避免它被解釋爲變量。

相關問題