如何在正则表达式中多次匹配行尾而不进行插值?

har*_*are 3 regex perl interpolation

如果我有一个包含新行的输入,例如:

[INFO]
xyz
[INFO]
Run Code Online (Sandbox Code Playgroud)

如何使用锚点拉出 xyz 部分$?我尝试了类似的模式/^\[INFO\]$(.*?)$\[INFO\]/ms,但 perl 给了我:

Use of uninitialized value $\ in regexp compilation at scripts\t.pl line 6.
Run Code Online (Sandbox Code Playgroud)

有没有办法关闭插值,使锚点按预期工作?

编辑:关键是行尾锚是一个美元符号,但有时可能需要将行尾锚散布在图案中。如果模式正在插值,那么您可能会遇到诸如 uninitialized 之类的问题$\。例如,这里可以接受的解决方案是/^\[INFO\]\s*^(.*?)\s*^\[INFO\]/ms,但这并不能解决第一个问题的症结。我已经将锚点更改为这样,^因此不会进行插值,并且通过此输入我可以自由地执行此操作。但是,当我确实想$在我的模式中引用 EOL 时该怎么办?如何编译正则表达式?

Ala*_*ore 5

这个问题是学术性的——无论如何,你的正则表达式中不需要锚点$。您应该使用\n来匹配换行符,因为$它只匹配换行符与其前面的字符之间的间隙。

编辑:我想说的是你永远不需要使用$这种方式。从一行到下一行的任何匹配都必须以某种方式消耗行分隔符。考虑你的例子:

/^\[INFO\]$(.*?)$\[INFO\]/ms
Run Code Online (Sandbox Code Playgroud)

如果确实编译成功,则将(.*?)从消耗第一个换行符开始并继续下去,直到匹配\nxyz,第二个换行符$将成功。但下一个字符是换行符,正则表达式正在寻找[,所以这不起作用。回溯之后,(.*?)会不情愿地再消耗一个字符——第二个换行符——但随后$会失败。

每当您尝试将 EOL 与$更多内容匹配时,您必须匹配的第一个“内容”将是换行符,那么为什么不匹配它呢?这就是 Perl 正则表达式编译器尝试将正则表达式解释$\为变量名的原因:行尾锚点后跟不是行分隔符的字符是没有意义的。