给出这样的字符串:
<a href="http://blah.com/foo/blah">This is the foo link</a>
...和像“foo”这样的搜索字符串,我想强调HTML文本中出现的所有“foo” - 但不在标签内。换句话说,我想得到这个:
<a href="http://blah.com/foo/blah">This is the <b>foo</b> link</a>
但是,简单的搜索和替换不起作用,因为它将匹配&lt; a&gt;中的部分网址。 tag的href。
因此,要以问题的形式表达以上内容:如何限制正则表达式以使其仅匹配HTML标记之外的文本?
注意:我保证所讨论的HTML永远不会像病态一样:
<img title="Haha! Here are some angle brackets to screw you up: ><" />
编辑是的,当然我知道CPAN中有复杂的库可以解析最令人发指的HTML,从而减少了对这种正则表达式的需求。在很多场合,这就是我会用的。但是,这不是其中之一,因为保持此脚本简短而没有外部依赖性非常重要。我只想要一行正则表达式。
编辑2:同样,我知道Template :: Refine :: Fragment可以解析我的所有HTML。如果我正在编写应用程序,我肯定会使用这样的解决方案。但这不是一个应用程序。它只不过是一个shell脚本。这是一个一次性代码。在这种情况下,作为一个可以传递的单个自包含文件非常有价值。 “嘿,运行这个程序”是比一个简单得多的指令,“嘿,安装一个Perl模块然后运行它 - 等等,什么,你以前从未使用过CPAN?好的,运行perl -MCPAN -e shell(最好作为根)然后它会问你一堆问题,但你真的不需要回答它们。不,不要害怕,这不会破坏任何东西。看,你不需要仔细回答每一个问题 - 只要一遍又一遍地输入。不,我保证,它不会破坏任何东西。“
现在将上述内容扩散到大量用户身上,他们想知道为什么他们一直在使用的简单脚本不再那么简单,当所有改变的是使搜索词变为粗体时。
因此,虽然Template :: Refine :: Fragment可能是其他人的HTML解析问题的答案,但它不是此问题的答案。我只想要一个正则表达式,它适用于非常有限的HTML子集,实际上会要求脚本解析。
答案 0 :(得分:10)
如果您可以绝对保证HTML中没有尖括号,而不是用于打开和关闭标签的尖括号,这应该有效:
s%(>|\G)([^<]*?)($key)%$1$2<b>$3</b>%g
答案 1 :(得分:7)
通常,您希望将HTML解析为DOM,然后遍历文本节点。我会使用Template :: Refine:
#!/usr/bin/env perl
use strict;
use warnings;
use feature ':5.10';
use Template::Refine::Fragment;
my $frag = Template::Refine::Fragment->new_from_string('<p>Hello, world. <a href="http://foo.com/">This is a test of foo finding.</a> Here is another foo.');
say $frag->process(
simple_replace {
my $n = shift;
my $text = $n->textContent;
$text =~ s/foo/<foo>/g;
return XML::LibXML::Text->new($text);
} '//text()',
)->render;
输出:
<p>Hello, world. <a href="http://foo.com/">This is a test of <foo> finding.</a> Here is another <foo>.</p>
无论如何,不要使用正则表达式解析结构化数据。 HTML不是“常规”,而是“无上下文”。
编辑:最后,如果你在程序中生成HTML,并且你必须在字符串上进行这样的转换,“UR DOIN IT WONG”。您应该构建一个DOM,并且只在转换完所有内容后对其进行序列化。 (但是,您仍然可以通过new_from_dom
构造函数使用TR。)
答案 2 :(得分:2)
以下正则表达式将匹配标记之间或标记之外的所有文本:
<.*?>(.*?)<.*?>|>(.*?)<
然后你可以根据需要对它进行操作。
答案 3 :(得分:0)
试试这个
(?=>)?(\w[^>]+?)(?=<)
它匹配标签之间的所有单词
答案 4 :(得分:0)
要从甚至嵌套的标签中剥离可变大小的内容,您可以使用此正则表达式实际上是一种迷你常规语法。 (注意:PCRE机器)
(?&LT; =&GT)((?:?\ W +)(:\ S *))(α1)*