1

我对正则表达式模式匹配有一个奇怪的行为

正则表达式是:

String regexp = "<h3.*>(.*)</h3>";

我有第一个案例:

<h3 class="pubAdTitleBlock">Title</h3>

在这种情况下,一切正常,matcher.group(1) 给我“标题”

我是第二种情况,我有一个嵌套在 h3 中的链接,如下所示:

<h3 class="pubAdTitleBlock "><a href="myLink" title="title">Title</a></h3>

这就是问题

在这种情况下 - matcher.find() 为真, - matcher.group(0) 为完整字符串, - 但 matcher.group(1)为空字符串

为什么 ?

我需要在里面<h3 ..>title</h3>和里面提取标题<h3 ...><a ...>title</a></h3>

4

4 回答 4

4

<h3.*>捕获<h3 class="pubAdTitleBlock "><a href="myLink" title="title">是因为正则表达式默认使用贪婪匹配算法。如果您希望它在 > 的第一个匹配后停止,则需要在 * 之后使用问号。试试这个:<h3.*?>(.*)</h3>

于 2012-09-11T13:43:58.210 回答
3

第一个.*将捕获," class="pubAdTitleBlock "><a href="myLink" title="title">Title</a"仅在捕获组之间留下零宽度空间。</a></h3>

您需要将其更改为类似的[^>]*内容(即“除 > 之外的任何内容”)。

于 2012-09-11T13:43:41.500 回答
2

答案是正则表达式的“贪婪”。在您的正则表达式中使用“大于”字符:

<h3.*>(.*)</h3>
     ^this one

您希望这将匹配开始 h3 标记的结尾,这将导致您的捕获组包含 h3 标记内的所有内容,就像第一个示例一样。

不过,正则表达式是贪婪的,这意味着它们会尝试尽可能多地使用文本。这导致您的正则表达式的第一部分,即

<h3.*>

匹配整个部分:

<h3 class="pubAdTitleBlock "><a href="myLink" title="title">Title</a>

请注意,匹配的字符串以与您的正则表达式 ( ) 相同的字符结尾>>该组现在捕获 this和 之间的剩余文本</h3>,这是一个空字符串。

有 3 个适合的解决方案。

  • 使用 xml 解析器,然后使用 xpath 来获取 h3 标记的内容(由于外部库等导致大量开销,但对于更大的项目来说绝对必须具备)
  • 通过附加 a使*-operator 非贪婪?,使 regex <h3.*?>(.*)</h3>在这里查看更多信息。
  • 修改正则表达式以在 h3 标记(并且没有其他标记!)关闭时立即开始捕获:<h3[^>]*>(.*)</h3>

希望这可以帮助!

于 2012-09-11T13:53:07.723 回答
0

感谢 Namida Aneskans,解决方案是:

String regexp = "<h3[^>]*>(<a[^>]*>)?([^<]+)(</a>)?</h3>";

所以第一组和第三组可以是空的,但第二组总是标题,谢谢!

于 2012-09-11T13:50:30.023 回答