在Perl中失败的RegEx查找和替换一行程序

0pizxfdo  于 2023-05-07  发布在  Perl
关注(0)|答案(3)|浏览(163)

我有下面的RegEx (<th>Password<\/th>\s*<td>)\w*(<\/td>),它与此HTML中的<th>Password</th><td>root</td>匹配:

<tr>
    <th>Password</th>
    <td>root</td>
</tr>

但是,此终端命令无法找到匹配项:

perl -pi -w -e 's/(<th>Password<\/th>\s*<td>)\w*(<\/td>)/$1NEWPASSWORD$2/g' file.html

它似乎与</th><td>之间的空白有关,但<\/th>\s*<td>在RegEx中可以工作,那么为什么在Perl中不能呢?
尝试用\s*替换\n*\r*\t*及其各种组合,但仍然不匹配。
任何帮助将不胜感激。

zsohkypk

zsohkypk1#

一次只能将替换应用于文件的一行。
可以使用-0选项一次读入整个文件,如下所示

perl -w -0777 -pi -e 's/(<th>Password<\/th>\s*<td>)\w*(<\/td>)/$1NEWPASSWORD$2/g' file.html

请注意,使用适当的HTML解析器(如HTML::TreeBuilder::XPath)来处理这样的数据是非常可取的,因为很难使用正则表达式来解释给定HTML结构的所有可能表示。

xjreopfe

xjreopfe2#

Perl一次计算一个文件的一行,在你的例子中,你试图匹配两行,所以perl永远不会在第一行找到它要找的字符串的结尾,也永远不会在第二行找到它要找的行的开头。
您可以暂时将file.html扁平化为一行(如果文件的小/性能不是那么重要,这可能有效),或者您需要编写更复杂的逻辑来跟踪找到的行。
请尝试搜索“multiline regex perl”:)

gdrx4gfi

gdrx4gfi3#

你可以使用sed来做这件事:

sed -i '/<th>Password<\/th>/{n;s!<td>[^<]*!<td>NEWPASSWORD!}' file.html

另一个sed版本:

sed -i '/<th>Password<\/th>/!b;n;s/<td>[^<]*/<td>NEWPASSWORD/' file.html

相关问题