正则表达式Lookbehind无法按预期工作

时间:2011-11-01 09:52:47

标签: c# regex

我在.net中有一个字符串。

<p class='p1'>Para 1</p><p>Para 2</p><p class="p2">Para 3</p><p>Para 4</p>

现在,我想只在标签p中找到文本(第1段,第2段,第3段,第4段)。

我使用了以下正则表达式,但它没有给我预期的结果。

(?<=<p.*>).*?(?=</p>)

如果我使用(?<=<p>).*?(?=</p>)它会给Para 2和Para 4这两个p标签都没有class属性?

我想知道代码的(?<=<p.*>).*?(?=</p>)有什么问题。

2 个答案:

答案 0 :(得分:5)

让我们使用RegexBuddy来说明这一点:

RegexBuddy Screenshot

你的正则表达式比你想象的更匹配 - 点匹配任何字符,所以它不关心标签边界。

它实际上在做什么:

  • (?<=<p.*>):断言当前位置前的字符串中有<p(后跟任意数量的字符) where ,后跟>
  • .*?:匹配任意数量的字符......
  • (?=</p>):...直到下一次出现</p>

您的问题有点不清楚,但如果您的计划是在<p>标记内查找文本而不管它们是否包含任何属性,那么您不应该使用正则表达式,而是使用DOM解析器,例如HTML agility pack

那就是说,如果你坚持正则表达式,试试

(?<=<p[^<>]*>)(?:(?!</p>).)*

Another screenshot

<强>解释

(?<=<p[^<>]*>)  # Assert position right after a p tag
(?:(?!</p>).)*  # Match any number of characters until the next </p>

答案 1 :(得分:1)

您是否尝试使用以下表达式?

<p[\s\S]*?>(?<text_inside_p>[\s\S]*?)</p>

名为text_inside_p的群组将包含所需的文字。