用于匹配模式嵌套的正则表达式
RegEx for matching schema nesting
我需要检测一个标签在另一个标签中的嵌套以引发错误。
示例:
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.');
}
如何解决这个问题?
检查标签嵌套的一种方法是检查,如果出现两个连续的 <amb
标签而中间没有 </amb>
标签,那么您可以拒绝表示存在嵌套的字符串标签。这种基于负面展望的正则表达式应该可以完成这项工作,
^(?!.*<amb(?:(?!<\/amb).)+<amb).+$
同样,另一种方法是检查两个连续的 <\/amb>
标签是否出现,中间没有 <amb
标签,这意味着标签是嵌套的,你可以再次使用这个否定来拒绝字符串向前看基于正则表达式,
^(?!.*<\/amb>(?:(?!<amb).)+<\/amb>).+$
让我知道这是否适合你。
您不需要为此使用正则表达式。 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()
以显示扩展此代码有多么容易。
我需要检测一个标签在另一个标签中的嵌套以引发错误。
示例:
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.');
}
如何解决这个问题?
检查标签嵌套的一种方法是检查,如果出现两个连续的 <amb
标签而中间没有 </amb>
标签,那么您可以拒绝表示存在嵌套的字符串标签。这种基于负面展望的正则表达式应该可以完成这项工作,
^(?!.*<amb(?:(?!<\/amb).)+<amb).+$
同样,另一种方法是检查两个连续的 <\/amb>
标签是否出现,中间没有 <amb
标签,这意味着标签是嵌套的,你可以再次使用这个否定来拒绝字符串向前看基于正则表达式,
^(?!.*<\/amb>(?:(?!<amb).)+<\/amb>).+$
让我知道这是否适合你。
您不需要为此使用正则表达式。 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()
以显示扩展此代码有多么容易。