我想在<p>
和</p>
之间捕获最多四组文字。我可以使用以下正则表达式来做到这一点:
<h5>Trivia<\/h5><p>(.*)<\/p><p>(.*)<\/p><p>(.*)<\/p><p>(.*)<\/p>
要匹配的文字:
<h5>Trivia</h5><p>Was discovered by a freelance photographer while sunbathing on Bournemouth Beach in August 2003.</p><p>Supports Southampton FC.</p><p>She has 11 GCSEs and 2 'A' Levels.</p><p>Listens to soul, R&B, <a href="/name/nm0005567/">Stevie Wonder</a>, <a href="/name/nm0291349/">Aretha Franklin</a>, <a href="/name/nm0713378/">Usher Raymond</a>, <a href="/name/nm0001391/">Michael Jackson</a> and <a href="/name/nm0584117/">George Michael</a>.</p>
输出四行文字。如果有更多琐事项目或<p>
次出现,它也可以按预期工作。
但如果少于4个琐事项目或<p>
组,则不会输出任何内容,因为它找不到第四组。如何使该组可选?
我已经尝试过:<h5>Trivia<\/h5><p>(.*?)<\/p>(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?
并根据http://gskinner.com/RegExr/工作,但如果我把它放在PHP代码中则不起作用。它只检测一个组并将所有内容放入其中。
答案 0 :(得分:1)
您可以使用问号使每个<p>...</p>
成为可选项:
$pattern = '~<h5>Trivia</h5>(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?~';
使用Dom也是一个不错的选择。
答案 1 :(得分:1)
这个神奇的词要么是“逃避”,要么是“分隔符”,请继续阅读。
第一个正则表达式:
<h5>Trivia<\/h5><p>(.*)<\/p><p>(.*)<\/p><p>(.*)<\/p><p>(.*)<\/p>
之所以有效,是因为您将/
等标记中的</h5>
个字符转义为<\/h5>
。
但是在你的第二个正则表达式中(正确地将每个段落包含在一个可选的非捕获组中,获取1到5个段落):
<h5>Trivia</h5><p>(.*?)</p>(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?
你忘了逃避那些/
个字符
那应该是:
$pattern = '/<h5>Trivia<\/h5><p>(.*?)<\/p>(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?(?:<p>(.*?)<\/p>)?/';
以上假设您将正则表达式置于两个/
“分隔符”字符之间(超出常规习惯)。
要深入潜入兔洞,应该注意到在php中,正则表达式的第一个和最后一个字符通常是“delimiter”,因此最后可以添加修饰符(如不区分大小写等。)
因此,您也可以使用~
字符(或#
等)作为分隔符,而不是转义正则表达式。
因此,您也可以使用您发布和封装的相同(第二个)正则表达式,例如:
$pattern = '~<h5>Trivia</h5><p>(.*?)</p>(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?(?:<p>(.*?)</p>)?~';
这是一个有效的(基于网络的)example,使用#
作为分隔符(只是因为我们可以)。