2011-01-05 191 views
2

我試圖打開一個文件,匹配一個特定的行,然後在該行周圍包裝HTML標籤。看起來非常簡單,但顯然我錯過了一些東西,並沒有正確理解Perl匹配的模式變量。Perl模式匹配變量問題

我匹配符合這樣的:

$line =~ m/(Number of items:.*)/i; 

這使整條生產線到$ 1中。我嘗試然後打印出我的新線是這樣的:

print "<p>" . $1 . "<\/p>; 

我希望它打印:

<p>Number of items: 22</p> 

不過,我真的開始這樣的:

</p>umber of items: 22 

我已經嘗試了各種變化 - 在單獨的一行上打印每一位,使用$ +和$ &等將$ 1設置爲一個新變量,並且我總是得到相同的結果。

我錯過了什麼?

+0

您描述的內容適用於我的機器。你能發佈你正在運行的實際代碼嗎? – 2011-01-05 21:14:18

+1

請包括您使用的完整(但最少)的代碼。 – 2011-01-05 21:14:27

回答

3

你能提供一個完整的代碼片段來證明你的問題嗎?我沒有看到它。

有一點需要注意的是,1美元和朋友指的是在該動態範圍內從上次成功匹配捕獲。你應該始終確保比賽使用一個前成功:

$line = "Foo Number of items: 97\n"; 
if ($line =~ m/(Number of items:.*)/i) { 
    print "<p>" . $1 . "<\/p>\n"; 
} 
+0

真的很好。我被前一場比賽中懸掛的1美元等被咬了 – justintime 2011-01-06 06:02:19

9

你在你的比賽,當其在畸形的輸出打印的結果有一個\ r。

編輯: 爲了進一步解釋,你的文件有可能是Windows風格\ r \ n行尾。 chomp將不會刪除\ r,然後它會陷入貪婪的匹配,並導致不愉快的輸出(\ r意味着返回到行首並繼續打印)。

您可以通過添加類似

$line =~ tr/\015//d; 
+0

鑑於上述行爲,這是一個很好的猜測。 Pedantry /澄清:'chomp'不會在默認情況下刪除'\ r',但如果您更改'$ /',也可以。通常這不是必需的,因爲perlio層會在輸入/輸出期間在平臺換行符和邏輯換行符之間進行轉換。需要注意的是,如果文件格式與平臺不匹配(例如,在* nix平臺上使用Windows風格的換行符處理文件),翻譯將不起作用。 – 2011-01-05 21:37:17

+0

這似乎是問題 - 我正在使用Cygwin並閱讀Windows文本文件。我是chomp(),但顯然沒有得到\ r。這對我之前所做的任何事情都沒有任何問題,文本被替換的方式並沒有讓我想到這一點。我現在明確地替換\ r,它工作正常。謝謝! – jeff 2011-01-05 21:57:18

3

您剛剛學會(備查)多麼危險.*可以刪除\ r。

這些日子以來,我一直對我所期望捕捉的東西儘可能精確。也許

$line =~ m/(Number of items:\s+\d+)/; 

然後我肯定沒有捕獲有問題的控制字符在第一個地方。無論Cygwin用Windows文件做什麼,我都可以保持無知。