2010-06-27 31 views
3

我正在尝试编写一个正则表达式来识别单行文本,并将下划线(_)识别为行连续字符。例如,“foo_ \ nbar”应该被视为单行,因为“foo”以下划线结尾。我想:这是否违反了“最左边最长”的原则?

$txt = "foo_\nbar"; 
print "$&\n" if $txt =~ /.*(_\n.*)*/; 

然而,这仅打印:

foo_ 

这似乎违背了Perl的正则表达式的 “最左边最长” 的规则!

有趣的是,如果我删除了正则表达式的最后一个星号(*),即:

$txt = "foo_\nbar"; 
print "$&\n" if $txt =~ /.*(_\n.*)/; 

确实打印:

foo_ 
bar 

但我需要的明星认识到“0或更多“延续!

我在做什么错?

+0

这是什么,你试图用这个正则表达式来实现呢?你想用它做什么? – Zaid 2010-06-27 14:14:02

+0

“认出单行文字,用下划线(_)识别为行续字符” – JoelFan 2010-06-27 14:15:39

回答

6

这究竟是为什么被@ysth解释。要解决它,你可以使用以下正则表达式:

/([^_\n]|_.)*/s 
5

Perl不做“最左边的”;相反,每个正则表达式都有一个明确的行为方式。只要正则表达式的其余部分完全匹配,您的首字母*就会尽可能匹配。为了防止它吞食_,这样做:

/(.*(?!(?<=_)\n)_\n)*.*/ 
+0

哇......这是一些沉重的正则表达式魔法...... – JoelFan 2010-06-27 14:43:03

+0

不是:'。*'匹配非换行符,'( ?''但不要以'(?<= _)'前面加上'_','\ n'换行符'''*'为尽可能多的行重复'.''和获得以下行 – ysth 2010-06-27 15:01:47

+0

ZyX's更好,但是对定义问题的直译性较差。 – ysth 2010-06-27 15:02:27

1

还有的正则表达式设计的两种基本形式:

POSIX定义了最左边,最长的味道。例如:将任何“a | b”更改为“b | a”对完全匹配没有任何作用。

PERL定义了左偏味。每个“a | b”检查左分支“a”,如果匹配,那么“b”不会被检查。因此“a | b”很少与“b | a”相同。这里的*就像()| a | aa | aaa | aaaa | ...

+4

不,a *就像... | aaaa | aaa | aa | a |()。一个*?就像()| a | aa | aaa | aaaa | .... – ysth 2010-06-27 21:11:25

相关问题