我正在尝试注释掉一堆 html 文档中的行项目条目。
我需要匹配一个具有一些变化的模式,并且替换将被包围的匹配模式<!-- -->
变化如下:
<li><a href="latest-news.htm" >Latest News</a></li>
<li><a href="pages/latest-news.htm" >Latest News</a></li>
<li><a href="../../latest-news.htm" >Latest News</a>
</li>
这些是主要的变体,但也可能有一些是latest-news.php 而不是.htm。另一种变化是只有一组../
到目前为止我有这个:
find ./ -name "*.htm" -exec perl -p0e 's/(^\s*<li><a href="((\.\.\/)*|pages\/)?latest-news\.(htm|php)"\s*>Latest News<\/a>\s*(\n)?\s*<\/li>\s*)/<!-- $1 -->/g' {} \; | grep -C 1 "latest-news" | grep -C 1 "latest-news"
我不知道那里出了什么问题,但我没有匹配任何东西。最后的 grep 应该向我显示找到的每个文件中这一行的每个实例,并且它们不会被注释掉。
我刚刚开始使用 perl 和正则表达式,这是迄今为止我所做的最复杂的尝试之一。
我正在尝试做的事情是否可行,或者是否有更好的方法来实现这一目标?
我尝试过使用一些正则表达式测试站点,但大多数没有标准的 perl 正则表达式测试,并且使用 PHP 正则表达式并匹配所有变体的站点在我尝试运行它时不起作用。
如果我可以添加更多信息,请告诉我。
几周前我能够获得一些匹配的多行变体,但我无法弄清楚我的命令的哪个版本做到了这一点。我目前正在从所有文件的备份开始,以便我可以测试更多内容。
我的版本
$> perl -v
This is perl 5, version 28, subversion 1 (v5.28.1) built for x86_64-linux-gnu-thread-multi
(with 61 registered patches, see perl -V for more detail)
$> grep -V
grep (GNU grep) 3.3
$> uname -mrs
Linux 5.3.0-24-generic x86_64
$> lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 19.10
Release: 19.10
Codename: eoan
更新
我将正则表达式搜索更新为:
(<li><a href="(\.\.\/|pages\/)*latest-news.(htm|php)"\s*>Latest News<\/a>\s*(\n)?\s*<\/li>)\n?
这捕获了除少数单行变化之外的所有变化。有些如果没有../
或page/
之前仍然没有匹配latest-news.htm
。存在一个在<li>
不匹配的行之前有更多空白的实例(3 个制表符与 1 个制表符或空格字符) 。
如果我在搜索模式中添加\s*
之前,<li>
注释将从上一行的末尾开始,但仍然无法捕获开头有更多空白的行。
<li><a href="latest-news.htm" class="current">Latest News</a></li>
^ 这是仍然不匹配的行。
答案1
也许是这样的:
perl -0777 -pe '
s{<li>\s*<a\s[^>]*href="[^"]*latest-news\.(?:htm|php)"[^>]*>\s*Latest News\s*</a>\s*</li>}
{<!-- $& -->}g' your-file.htm
就足够了。
请注意,如果您不启用多行模式(带有 标志m
),^
则仅匹配主题的开头(每个 NUL 分隔的记录-0
,整个输入用-0777
),而不是开头主题中的任何一行。另请注意,\s
换行符也匹配。如果您只想匹配水平间距,请使用\h
(但据我所知,HTML 在水平和垂直之间没有区别,NL 和 SPC 就其语法而言是可以互换的,至少在<pre>
、CDATA...
、 带引号的属性值之外......)。
为了避免在已经注释的部分中进行替换,您可以这样做:
perl -0777 -pe '
s{(<!--.*?-->)|<li>\s*<a\s[^>]*href="[^"]*latest-news\.(?:htm|php)"[^>]*>\s*Latest News\s*</a>\s*</li>}
{$1 // "<!-- $& -->"}gse' your-file.htm