0

基本上我需要匹配不属于封闭 <p> 标记的 HTML 中的任何 / 。这是我到目前为止所得到的,但它并没有按预期工作,我已经尝试了一段时间。

((?<!(p))\/(?!(>))) | ((?<!(<))\/(?!(p)))

我还需要正则表达式才能在 Java 中工作。

举个例子:

<div>测试</div> <span>测试</span> <p>某事<p/> </p>

我希望它匹配/除了最后<p>标签中的之外的所有内容!

4

2 回答 2

0
/(?!p)

这似乎有效。但我不确定问题是什么。

<div>test</div> <span>test</span> <p>something<p/> </p>
matches:  /                /                    /
于 2013-10-08T13:59:12.387 回答
0

幸运的是,Java 同时支持lookbehind 和lookahead(相比之下,我大部分时间都在使用的语言JavaScript 只支持lookahead)。

所以你正在寻找的模式是:

(?<!<p)/(?!p>)

此模式将匹配任何前面既不是 a<p也不是后跟 a的斜杠p>。因此它排除<p/>以及</p>

前瞻/后瞻断言(通常称为“零宽度”断言)实际上并未包含在匹配中,这听起来像是您想要的。它基本上断言你试图匹配的东西前面是(lookbehind)或后面是(lookahead)一个子表达式。在这种情况下,我们使用否定断言(前面没有/后面没有)。

使用正则表达式解析 HTML 是一项棘手的工作。正如一个答案所指出的那样,HTML 是上下文无关的,因此不能完全被 HTML 解析,从而留下了 HTML 混淆匹配的可能性。我们甚至不要开始使用格式错误的 HTML。

不过,我会考虑以下对空标签的常见变体:

<p />

为了处理这个问题,我会在匹配中添加一些空格:

(?<!<p\s*)/(?!p>)

您可能会遇到问题的地方是奇怪的空格(仍然是有效的 HTML)。以下斜杠将与上述正则表达式匹配:

< p/>
<p/ >

这可以通过在您的正则表达式中添加更多的空格重复来解决。如前所述,这也将匹配文本中的斜线,因此以下输入将仅匹配一个斜线(文本中的那个):

<p>some text / other text</p>

最后,当然还有 CDATA 组。以下输入将匹配 NO 斜杠:

<![CDATA[This <p/> isn't actually a tag...it's just text.]]>
于 2013-10-08T14:09:33.967 回答