PHP Regex - 在特定模式后删除特定字符串

时间:2016-10-31 08:59:54

标签: php regex

我在WordPress中创建列短代码,并且它总是在标记后添加</p>

因此转储变量的原始HTML结果如下所示:

<column class="size-5"></p>
....
</column>

我想用正则表达式删除那个孤独</p>,所以我做了这个:

$content = preg_replace("/(?!<column[^<]+)<\/p>/", '', $content);

我在排除列标记时匹配</p>。这是Regexr link

在regexr(我假设使用JS语法)中,它完美地运行。但在PHP中,它匹配每个</p>并删除它。

我在?<!?>!后面尝试了许多变体但不起作用。

之前有没有人遇到过同样的问题?

由于

1 个答案:

答案 0 :(得分:0)

首先,您应该知道使用正则表达式操纵HTML是易受攻击的,并且可能无法在100%的情况下使用任意HTML代码。只有当你知道自己在做什么时才能使用它(你以独特的方式自己生成HTML,或者HTML提供程序是已知的,并使用unqiue方法进行HTML转义等)。

接下来,您不需要使用任何负面的前瞻。您使用的模式与</p>子模式的起始子序列中的任何<column[^<]+匹配,这始终为真,并且您有效地匹配任何 </p>。< / p>

如果您要删除某些特定已知上下文中显示的某些文字,您可以依赖捕获您需要的内容并仅匹配你想要替换什么。唯一要做的是将您需要保留的模式部分包含在(...)中,并在替换模式中使用该组的反向引用。

使用

$content = preg_replace('/(<column\b[^<]*>)<\/p>/', '$1', $content);

或者,在PCRE中,您可以使用省略到目前为止匹配的全文的\K运算符

$content = preg_replace('/<column\b[^<]*>\s*\K<\/p>/', '', $content);

你不必在替换模式中使用任何反向引用。

我添加了\b(字边界)以确保column与整个字匹配。由于它仍然可以与column中的column-editor匹配,因此您可能希望使用<column\b[^<]*>重新<column(?:\s[^<]*)?>