2011-07-07 54 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"; 
}