找到单词,但不是在链接中


find word but not in a link

我需要一个reg表达式,它会在html中找到目标单词或单词(因此在标签之间),但不在锚或脚本标签中。我做了很长时间的实验,想出了这个

(?!<(script|a).*?>)('btype 2 diabetes'b)(?!<'/(a|script)>)

假设这里要替换的目标是2型糖尿病

我认为这是一个常见的问题,但所有的引用都是锚的一部分,而不是不在锚或脚本标签中,而是在它们和其他标签之间

这是一个测试数据我都用过http://regexpal.com/和http://gskinner.com/RegExr/用上面的表达式和下面的测试数据,尽我所能,我只是不能排除锚点或脚本标签中的位,但不排除锚点或脚本标签之间的位。

在测试数据下面只有"2型糖尿病"里面

<p></p>

应该被捕获。

<a href="https://www.testsite.org.uk">
<div><img alt="logo" src="/images/logo.png" height="115" width="200" /></div>
<h2>Healthy Living for People with type 2 Diabetes</h2>
</a>
<p>type 2 Diabetes</p>
<a id="logo" href="https://www.help-diabetes.org.uk">
<div><img alt="logo" src="/images/logo.png" height="115" width="200" /></div>
<h2>Healthy Living for People with type 2 Diabetes</h2>
</a>

这个问题不要使用正则表达式。使用html解析器。下面是一个使用BeautifulSoup的python解决方案:

from BeautifulSoup import BeautifulSoup
with open('Path/to/file', 'r') as content_file:
    content = content_file.read()
soup = BeautifulSoup(content)
matches = [el for el in soup(text=re.compile(r'type 2 diabetes')) if el.name not in ['a','script']]
# now you can modify the matched elements
with open('Path/to/file.modified', 'w') as output_file:
    output_file.write(str(soup))

要在目标单词出现时进行替换,避免使用a脚本标记,您必须尝试在目标单词之前匹配这些标记(及其内容)。例子:

$subject = <<<LOD
<a href="https://www.testsite.org.uk">
<div><img alt="logo" src="/images/logo.png" height="115" width="200" /></div>
<h2>Healthy Living for People with type 2 Diabetes</h2>
</a>
<p>type 2 Diabetes</p>
<a id="logo" href="https://www.help-diabetes.org.uk">
<div><img alt="logo" src="/images/logo.png" height="115" width="200" /></div>
<h2>Healthy Living for People with type 2 Diabetes</h2>
</a>
LOD;
$targets = array('type 2 diabetes', 'scarlet fever', 'bubonic plague');
$pattern = '~<(a|script)'b.+?</'1>|'b(?>' . implode('|', $targets) . ')'b~si';
$result = preg_replace_callback($pattern,
    function ($m) { return (isset($m[1])) ? $m[0] : '!!!rabbit!!!'; },
    $subject);
echo htmlspecialchars($result);

回调函数返回ascript标记,与设置第一个捕获组时相同,或者返回替换字符串。

注意,如果希望为每个目标单词指定一个替换词,可以使用关联数组:

$corr = array( 'type 2 diabetes' => 'marmot',
               'scarlet fever'   => 'nutria',
               'bubonic plague'  => 'weasel'  );
$pattern = '~<(a|script)'b.+?</'1>|'b(?>'
         . implode('|', array_keys($corr)) . ')'b~si';
$result = preg_replace_callback($pattern,
    function ($m) use ($corr) {
        return (isset($m[1])) ? $m[0] : $corr[strtolower($m[0])];
    },
    $subject);
请记住,处理html的最好方法是使用DOM