2011-07-07 81 views
-2

我的perl越來越生鏽。它只打印「匹配=」,但$ 1是空白的!?!不能得到perl正則表達式工作

編輯1:爲什麼h#$! downvoted這個?沒有錯誤的問題。如果你不喜歡它,繼續下一個!

$crazy="abcd\r\nallo\nXYZ\n\n\nQQQ"; 
if ($crazy =~ m/([.\n\r]+)/gsi) { 
    print "matched=", $1, "\n"; 
} else { 
    print "not matched!\n"; 
} 

編輯2:這是更新的正則表達式的代碼片段的偉大工程!

$crazy="abcd\r\nallo\nXYZ\n\n\nQQQ"; 
if ($crazy =~ m/([\s\S]+)/gsi) { 
    print "matched=", $1, "\n"; 
} else { 
    print "not matched!\n"; 
} 

編輯3:哈哈,我看到的perl警察罷工再次!!!

+1

你到底要怎麼搭配? – Qtax

+0

'ord($ 1)'返回13,所以它匹配第一個'\ r'。 – Mike

+0

一切,整個字符串,這就是我期望被打印 – Saideira

回答

5

我不知道如果這是你確切的問題,但裏面方括號,'.'只是尋找一段時間。我沒有看到投入的一段時間,所以我想知道你的意思。

除了這段時間,角色類的其餘部分正在尋找連續的空白。因爲您沒有使用ultiline開關,所以換行符被計爲空格(和任何字符),但沒有指示要掃描超出第一個記錄分隔符。但是,由於你打印出來的方式,它也表明你的意思超過了字面上的時間,如上所述。

+0

我的目標是匹配每一個字符(顯然,這是一個簡化的例子)。點匹配每個字符,除了新行符號,所以我把它們放在括號內。如果我把「m」放在前面或在前面的末尾,沒關係,$ 1仍然是空白的 – Saideira

+0

@Saideira,看到我的第一句話。 「點匹配每個字符,除了新行符號」 - 除了*在字符類內*(方括號) – Axeman

+0

是的,在字符類中,點只是一個點。你的/ s在那裏沒有影響。 –

2

$1包含空白區域,這就是爲什麼你沒有看到它在這樣的打印,只是添加一些東西后面/引用它。

例子:

perl -E "qq'abcd\r\nallo\nXYZ\n\n\nQQQ'=~/([.\n\r]+)/gsi;say 'got(',length($1),qq') >$1<';" 
got(2) > 
< 

更新您的意見:

要匹配一切,你可以簡單地使用/(.+)/s

+0

不起作用。使用預編譯的Perl for msys。平臺錯誤? – Saideira

+0

@Saideira,已更新。對於我的例子,你可能需要Perl 5.12或更新的版本,因爲我使用'-E'和'say',你可以用'-e'和'print'來代替它們。 – Qtax

+0

@Saideria你使用的是什麼版本的Perl? Qtax發送給你的代碼需要Perl 5.10或更高版本('-E'標誌自5.10開始是新的,並打開了可選功能,如'say'函數)。 –

1

[.](字符類內的點)並不意味着「匹配任何字符」,它只是意味着匹配文字.字符。因此,在沒有任何點輸入字符串,

m/([.\n\r]+)/gsi 

將只匹配\n\r字符的字符串。 隨着/s修改,你已經問正則表達式引擎,包括新行與.(匹配任何字符),所以你可以只寫

m/(.+)/gsi 
+0

'/ i'在那個正則表達式中沒有用處(它沒有大寫或小寫字符來影響它)。 –

2

.字符類是文字句,不匹配任何內容。你真正想要的是/(.+)/s/g標誌表示匹配多次,但是您在標量上下文中使用正則表達式,所以它只會匹配第一個項目。 /i標誌使正則表達式不區分大小寫,但在正則表達式中沒有大寫字母。 \s標誌使.匹配換行符,並且它始終匹配"\r",因此,而不是[.\n\r],您可以使用.

然而,/(.+)/s將任意字符串匹配一個或多個字符,所以你將與

my $crazy="abcd\r\nallo\nXYZ\n\n\nQQQ"; 

if (length $crazy) { 
    print "matched=$crazy\n"; 
} else { 
    print "not matched!\n"; 
} 

有可能更好,你打算做這樣的事情:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $crazy = "abcd\r\nallo\nXYZ\n\n\nQQQ"; 

while ($crazy =~ /(.+)[\r\n]+/g) { 
    print "matched=$1\n"; 
} 

但這可能會更好措辭:

#!/usr/bin/perl 

use strict; 
use warnings; 

my $crazy = "abcd\r\nallo\nXYZ\n\n\nQQQ"; 

for my $part (split /[\r\n]+/, $crazy) { 
    print "matched=$part\n"; 
} 
3

Axeman是正確的;你的問題是字符類中的.不符合你的期望。

默認情況下,.在字符類(而不是反斜線)之外匹配任何字符,而不是換行符。如果你想換行包括,你在你的正則表達式指定/ s標誌(你似乎已經有),或者把.(?s:...)組:

my $crazy="abcd\r\nallo\nXYZ\n\n\nQQQ"; 
if ($crazy =~ m/((?s:.+))/) { 
    print "matched=", $1, "\n"; 
} else { 
    print "not matched!\n"; 
}