我希望匹配BEGIN和END之间关于空格和换行符的任何内容。
即。我有以下文字:
BEGIN END BEGIN a END
我想要写一个可以返回两个匹配的正则表达式:''并且' a'。目前我有这个:
/\s*BEGIN\s*\n(.*?)\n\s*END\s*\n/sg
然而,这个只给出一个匹配:
END
BEGIN
a
您会看到问题所在:第一个BEGIN与第二个END配对。我希望它与第一个END配对。它看起来像
.*?
与空字符串不匹配 - 即它与贪婪匹配。
答案 0 :(得分:8)
222224466888AA Expected
"BEGIN\n\nEND\n\nBEGIN\n a\nEND\n"
22222334455555555555555555566888AA Got
111 22222 333 44 55555 66 777 888 999 AA
/\s* BEGIN \s* \n (.*?) \n \s* END \s* \n/xsg
正如您所看到的,第一件与预期不符的是\s*
之后的BEGIN
。您希望\s*
匹配除换行符之外的任何空格,这可以使用[^\S\n]*
完成。
/^ [^\S\n]* BEGIN [^\S\n]* \n (.*?) \n [^\S\n]* END [^\S\n]* \n/xsmg
如您所见,非贪婪修饰符在用于避免匹配某些内容时容易失败。如果你想要更强大的东西,你可以使用以下习语:
(?:(?!STRING).)*
是STRING
,[^CHAR]*
是CHAR
这会给你
/
^ [^\S\n]* BEGIN [^\S\n]* \n
( (?:(?! ^ [^\S\n]* (?: BEGIN | END ) [^\S\n]* \n ).)* ) \n
[^\S\n]* END [^\S\n]* \n
/xsmg
答案 1 :(得分:0)
怎么样:
my $str = "BEGIN
END
BEGIN
a
END";
my $re = qr~BEGIN\s+(.*?)\s+END~;
my (@m) = $str =~ /$re/sg;
dump@m;
<强>输出:强>
("", "a")
答案 2 :(得分:0)
我找到了这个网站,它似乎描述了你的问题:
http://www.regular-expressions.info/dot.html
根据该页面上的信息,我建议您尝试BEGIN\n?([^\r\n])\n?END
答案 3 :(得分:0)
在@Wiseguy的暗示之后,贪婪的空白匹配导致了这个问题。当我将它们转换为非贪婪时,它开始在所有情况下工作,除了在BEGIN和END之间几乎没有任何东西:
BEGIN
END
我通过添加非捕获组来解决它:
/BEGIN\s*\n(?:(.*?)\n)??\s*END\s*\n/sg