我需要检测一个标签在另一个标签中的嵌套以引发错误。
示例:
anything <amb id="1">word1</amb> anything <amb id="2">word2</amb> anything // OK
anything <amb id="1">anything<amb id="2">word2</amb>anything</amb> anything // KO
因此有必要检测标签<amb...
和</amb>
之间的标签<amb...
或</amb>
我有一个模式的开始,但是我无法管理标签的嵌套状态。
// #\<amb(.*?)\<\/amb\># => OK : detect the first level
$pattern = '#\<amb(?!\<amb)\<\/amb\>#'; // KO
if(preg_match($pattern, $string)) {
throw new Exception('No nested tags are allowed.');
}
我该如何解决这个问题?
答案 0 :(得分:3)
检查标签嵌套的一种方法是检查是否出现了两个连续的<amb
标签,而中间没有</amb>
标签,那么您可以拒绝表示标签嵌套的字符串。这种基于负面展望的正则表达式应该可以胜任工作,
^(?!.*<amb(?:(?!<\/amb).)+<amb).+$
类似地,另一种方法是检查两个连续的<\/amb>
标签是否出现而中间没有<amb
标签,这意味着标签是嵌套的,并且可以再次使用此否定的外观拒绝字符串基于正则表达式,
^(?!.*<\/amb>(?:(?!<amb).)+<\/amb>).+$
让我知道这是否对您有用。
答案 1 :(得分:1)
您不需要正则表达式。 They are a pain。您可以做的是炸开</amd>
上的字符串,然后检查每个部分中最多包含一个<amb
。像这样:
function correctlyNested($html, $tag)
{
foreach (explode("</$tag>", strtolower($html)) as $part) {
if (substr_count($part, "<$tag") > 1) return false; // it is KO
}
return true; // it is OK
}
$tests = ['anything <amb id="1">word1</amb> anything <amb id="2">word2</amb> anything',
'anything <amb id="1">anything<amb id="2">word2</amb>anything</amb> anything'];
foreach ($tests as $test) {
echo $test . (correctlyNested($test, "amb") ? " // OK<br>" : " // KO<br>");
}
此代码易于理解和维护。我添加了strtolower()
,以说明扩展此代码有多么容易。