在一行中匹配多个模式

时间:2013-01-31 08:15:15

标签: java regex

有人可以告诉我为什么我的模式:<p(\s+(.*)?)?>(.[^</p>]*)?</p>无法正常工作。示例匹配:

  
      
  1. <p>This is a test and anything can be here even other <tags>tags</tags></p>
  2.   
  3. <p style="test">This is a test</p>
  4.   
  5. <p></p>
  6.   

如果以上都是一行,它应该找到3个独立的模式。下面的链接展示了它的真实行为,这很奇怪......

http://regexr.com?33jrn

找到的匹配应始终在找到<p时立即开始,并在找到</p>后立即停止

3 个答案:

答案 0 :(得分:3)

你的正则表达式存在一些问题。让我们看看它们的样子。

这是你的正则表达式: -

<p(\s+(.*)?)?>(.[^</p>]*)?</p>
  • 问题1: - 注意模式(.*)?。这不符合你的想法。这不是强制*量词的不情愿行为。相反,它是对贪婪的(?)量词强制执行可选的量词*。它只是意味着匹配0 or 1重复(.*)。为了使其不情愿,您需要在括号内移动?。因此,您需要使用(.*?)代替(.*)?
  • 问题2: - [^</p>]不会否定</p>而是否定 - <, /, p, >作为单独的字符。请注意,在字符类中,每个字符都是字面意思。那里没有分组。因此,(.[^</p>]*)表示匹配character,如果0 or more repetition之后没有[</p>]。那不是你想要的。如果您想匹配不是</p>的序列,那么您可以使用负面预测: - ((?!</p>).)*。现在,这将首先检查以下序列是否不是</p>,然后它匹配下一个字符。

所以,你的正则表达式应该是: -

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

或者,您甚至可以将正则表达式简化为: -

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

答案 1 :(得分:1)

试试这个:

<p.*?>.*?</p>

请在此页面上阅读有关贪婪和不情愿的内容:“Differences Among Greedy, Reluctant, and Possessive Quantifiers”。

答案 2 :(得分:1)

问题出在(.[^</p>]*)?,意思是:

  • 单个字符
  • 后跟任意一次,但不是</p也不是>

我想你想要而不是</p>字符串n次,但这不是这样做的。

请尝试使用.*?<p(\s+(.*)?)?>.*?</p>

虽然.*表示匹配最长字符串,但.*?表示匹配最短字符串

例如,对于字符串#foo#bar#.*将匹配#foo#bar#,而.*?将匹配#foo#