2016-05-24 81 views
1

關於如何在Perl中執行多行正則表達式有許多問題。他們中的大多數提到s開關,使點匹配換行符。但是,我想匹配一個確切的短語(所以,而不是模式),我不知道換行符會在哪裏。所以問題是:你可以忽略換行符,而不是將它們與.匹配?不帶點的Perl正則表達式多行匹配

MWE:

$pattern = "Match this exact phrase across newlines"; 

$text1 = "Match\nthis exact\nphrase across newlines"; 
$text2 = "Match this\nexact phra\nse across\nnewlines"; 

$text3 = "Keep any newlines\nMatch this exact\nphrase across newlines\noutside\nof the match"; 

$text1 =~ s/$pattern/replacement text/s; 
$text2 =~ s/$pattern/replacement text/s; 
$text3 =~ s/$pattern/replacement text/s; 

print "$text1\n---\n$text2\n---\n$text3\n"; 

我可以把圓點圖案代替空格("Match.this.exact.phrase"),但是,這並不對第二個例子工作。我可以刪除所有換行符作爲預處理,但我想保留不屬於匹配的換行符(如第三個示例中所示)。

所需的輸出:

replacement text 
--- 
replacement text 
--- 
Keep any newlines 
replacement text 
outside 
of the match 
+0

大多數情況下,您將換行符視爲空格。然後有一次你想忽略它。做任何一個都很簡單。做這兩件事幾乎是不可能的。 – ikegami

回答

2

這聽起來像你想改變你的「確切」模式來匹配任何地方的換行符,也允許換行而不是空格。所以改變你的模式來做到這一點:

$pattern = "Match this exact phrase across newlines"; 
$pattern =~ s/\S\K\B/\n?/g; 
$pattern =~ s/ /[ \n]/g; 
+0

注意:這裏假設'$ pattern'不是一個正則表達式模式,而是一個字符串文字來準確找到。 – ikegami

+0

這與'$ pattern =「*」'和'$ text =「*」'不匹配。 – ikegami

+0

如果'$ pattern =「foo-bar」'和'$ text =「foo \ n-bar」',這將不匹配。 – ikegami

3

只需更換一個字符類匹配一個空格或換行文字空間:如果你想更寬鬆

$pattern = "Match[ \n]this[ \n]exact[ \n]phrase[ \n]across[ \n]newlines"; 

或者,使用\s或者\s+,因爲\s也匹配換行符。

+0

我的第二個例子('phra \ nse')怎麼樣? – Marijn

1

這當然是醜陋,但它的工作原理:

M\n?a\n?t\n?c\n?h\st\n?h\n?i\n?s\se\n?x\n?a\n?ct\sp\n?h\n?r\n?a\n?s\n?e\sa\n?c\n?r\n?o\n?s\n?s\sn\n?e\n?w\n?l\n?i\n?n\n?e\n?s 

對於每對字母詞裏面,讓他們之間的換行與\n?。並用\s替換正則表達式中的每個空格。

可能無法使用,但它能夠完成任務;)

Check it out at regex101

3

大多數情況下,你正在將換行符視爲空格。如果這就是你想要做的一切,你需要的只是

$text =~ s/\n/ /g; 
$text =~ /\Q$text_to_find/ # or $text =~ /$regex_pattern_to_match/ 

然後有一次你想忽略它。如果這是你想做的事,所有你需要的是

$text =~ s/\n//g; 
$text =~ /\Q$text_to_find/ # or $text =~ /$regex_pattern_to_match/ 

做既幾乎是不可能的,如果你有一個正則表達式匹配模式。但是你似乎想要匹配字面文本,這樣就可以打開一些可能性。

(my $pattern = $text_to_find) 
    =~ s/(.)/ $1 eq " " ? "[ \\n]" : "\\n?" . quotemeta($1) /seg; 
$pattern =~ s/^\\n\?//; 
$text =~ /$pattern/ 
+0

經過測試。做了一些修復。 – ikegami

+0

我認爲在所需匹配之前剝去換行符 – ysth