为什么这个perl正则表达式没有正确执行DOTALL?

时间:2013-05-31 16:20:20

标签: regex perl

我在命令行中使用perl regex操作来修改文件(在linux中),并想知道为什么它无法修改文件。这是正则表达式:

perl -i -pe 'undef $/; s#(<web-app[^>]*>).*?(</web-app>)#\1CHEESE\n\2#gsi' filePath/web.xml

现在,这应该正确匹配多行块。但事实并非如此。样本输入:

<web-app xmlns= "http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
         version="2.5">
<stuff goes here and tags and things>
</web-app>

然而没有任何改变。 Dotall应该是匹配的,这适用于在线正则表达式测试工具,但是在Perl中失败了。我做错了什么?

2 个答案:

答案 0 :(得分:7)

您希望立即读取整个文件并进行替换,而-0777参数就是这样做的。

perl -i -0777 -pe 's#(<web-app[^>]*>).*?(</web-app>)#\1CHEESE\n\2#gsi' filePath/web.xml

以前$/在第一行已被读取时设置,因此正则表达式在部分内容上无法匹配。

答案 1 :(得分:2)

使用-p选项时,脚本位于while (<>)循环体内。所以undef $/;直到你进入循环后才会被执行。因此,第一次迭代将处理第一行输入,第二次迭代将处理输入的其余部分。

您可以使用BEGIN块在循环之前插入代码:

perl -i -pe 'BEGIN {undef $/;} s#(<web-app[^>]*>).*?(</web-app>)#\1CHEESE\n\2#gsi' filePath/web.xml