如何在重复之间匹配可选组?

时间:2017-05-05 14:04:06

标签: regex

我需要匹配HTML元素和可选的'parent-name'属性。

<rect x='300' y='1150' rx='10' ry='10' width='361' height='65' state-name='ReadyForProduction' parent-name='Active' fill='url(#grad_#9FA0DD)' style='stroke: black; stroke-width:1; opacity:1.0'/>
<rect x='300' y='1150' rx='10' ry='10' width='361' height='65' state-name='SomethingElse' fill='url(#grad_#9FA0DD)' style='stroke: black; stroke-width:1; opacity:1.0'/>

此表达式仅匹配具有属性的元素:

<rect[^<]*?(?:parent-name='(.+?)')[^<]*?\/>

这个带有量词?的表达式匹配所有元素并忽略属性:

<rect[^<]*?(?:parent-name='(.+?)')?[^<]*?\/>

我应该如何匹配所有主题并在重复之间捕获组(如果存在)?

Regex101

3 个答案:

答案 0 :(得分:1)

这个应符合您的需求:<rect.*?((parent-name)='([^']*)').*?\/>|<rect.*?\/>

Demo

PHP代码段

$re = '/<rect.*?((parent-name)=\'([^\']*)\').*?\/>|<rect.*?\/>/';
$str = '<rect x=\'300\' y=\'1150\' rx=\'10\' ry=\'10\' width=\'361\' height=\'65\' state-name=\'ReadyForProduction\' parent-name=\'Active\' fill=\'url(#grad_#9FA0DD)\' style=\'stroke: black; stroke-width:1; opacity:1.0\'/>

<rect x=\'300\' y=\'1150\' rx=\'10\' ry=\'10\' width=\'361\' height=\'65\' state-name=\'ReadyForProduction\' fill=\'url(#grad_#9FA0DD)\' style=\'stroke: black; stroke-width:1; opacity:1.0\'/>';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);

// Print the entire match result
var_dump($matches);

PHP Online demo

答案 1 :(得分:0)

您可以将父级名称之前的部分也推送到非捕获组。如果没有父名称,非捕获组后面的后缀将匹配它。

^<rect(?:[^>]*?parent-name='(.+?)')?[^>]*?\/>

Demo

答案 2 :(得分:0)

<rect(?:(?:\sparent-name='[^']*')|\s[A-z-]+='[^']*')*\/>

使用Regex,有助于尽可能具体。所以基本上,匹配标记,并通过匹配有效属性来循环,首先要捕获它们(第一个匹配优先级)。这也将使正则表达式比大型文档更有效。