Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 用于模板化子循环的递归正则表达式_Regex_Templates_Recursion - Fatal编程技术网

Regex 用于模板化子循环的递归正则表达式

Regex 用于模板化子循环的递归正则表达式,regex,templates,recursion,Regex,Templates,Recursion,所以我研究了递归正则表达式匹配的其他解决方案,但是我仍然没有得到一个合适的正则表达式匹配 我有一个我想自己解析的通用把手样式模板,一个带有标题的表: <table> <thead> <tr> {{#each columns as col }}<th>{{col}}</th>{{/each}} </tr> </thead> <tb

所以我研究了递归正则表达式匹配的其他解决方案,但是我仍然没有得到一个合适的正则表达式匹配

我有一个我想自己解析的通用把手样式模板,一个带有标题的表:

<table>
    <thead>
        <tr>
            {{#each columns as col }}<th>{{col}}</th>{{/each}}
        </tr>
    </thead>
    <tbody>
        {{#each rows as row }}
        <tr>
            {{#each row as col }}<td>col</td>{{/each}}
        </tr>
        {{/each}}
    </tbody>
</table>
正则表达式很好地匹配了
中的
{{{each columns…
,但它似乎忽略了
{124;(?R)
部分,只匹配
{{{each}行…
,直到第一个
{/each}
。我当然希望它能够匹配内部和外部的
#表达式。如何匹配?这可能比简单的嵌套括号复杂得多

(在遇到类似的事情之前,我一直觉得自己是RegEx的专业人士。我已经尝试了一段时间,regular-expressions.info让我更加困惑。)



我目前正在做
{{{{each#u sub…}}{{/each#u sub}}}来解决这个问题
因此,我的正则表达式不会在第一个结束标记上停止,但这显然是一种次优的方法。我还有其他几个应用程序可以从递归正则表达式中受益,但无法找出我做错了什么。

它并没有忽略递归,只是永远无法到达它。因为
*?
能够匹配您的delimiters(
{{{each…}}
{{/each}}
),它匹配它找到的第一个结束分隔符并报告成功,而不需要递归

要使此技术起作用,
(?R)
前面的分支必须匹配任何非分隔符的内容。由于分隔符由多个字符组成,您不能像链接到的问题中那样使用否定字符类。相反,您需要使用:

(?:(?!{{[#/]每个\b)*
这与
*
相同,只是在它使用每个字符之前,它会检查以确保它不是
{{{each
{/each
的开头。这里是上下文:

{{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
如果第一个分支失败,则表示您遇到了类似于分隔符的问题。如果它是一个开始分隔符,则第二个分支将接管并尝试递归地匹配整个模式。否则,它将从循环中弹出(请注意组后面的
*
,您也没有看到)并尝试匹配结束分隔符

虽然上面的正则表达式在有效输入上可以很好地工作,但如果输入格式不正确,它会遭受灾难性的回溯。为了避免这种情况,您可以使用替代选项(正如@Wiktor在其评论中所做的):

{{{each\s+(\w+)\s+as\s+(\w+)\s*}(?:(?!{{[}/]each\b)。*(?:(?:(?:(?:(?!{[}/]each\b)。*)*{{/each}
这是一个更具可读性的版本,添加了所有格量词,以挤出更多的速度:

{{\#每个\s+(\w+)\s+as\s+(\w+)\s*}
(?:(?!{{[#/]各\b)*+
(?:
(?R)
(?:(?!{{[#/]各\b)*+
)*+
{{/每个}}

它没有忽略递归,它只是永远不会到达它。因为
*?
能够匹配您的分隔符(
{{{each…}}
{/each}}
),它匹配它找到的第一个结束分隔符并报告成功,而不需要递归

要使此技术起作用,
(?R)
前面的分支必须匹配任何非分隔符的内容。由于分隔符由多个字符组成,您不能像链接到的问题中那样使用否定字符类。相反,您需要使用:

(?:(?!{{[#/]每个\b)*
这与
*
相同,只是在它使用每个字符之前,它会检查以确保它不是
{{{each
{/each
的开头。这里是上下文:

{{\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
如果第一个分支失败,则表示您遇到了类似于分隔符的问题。如果它是一个开始分隔符,则第二个分支将接管并尝试递归地匹配整个模式。否则,它将从循环中弹出(请注意组后面的
*
,您也没有看到)并尝试匹配结束分隔符

虽然上面的正则表达式在有效输入上可以很好地工作,但如果输入格式不正确,它会遭受灾难性的回溯。为了避免这种情况,您可以使用替代选项(正如@Wiktor在其评论中所做的):

{{{each\s+(\w+)\s+as\s+(\w+)\s*}(?:(?!{{[}/]each\b)。*(?:(?:(?:(?:(?!{[}/]each\b)。*)*{{/each}
这是一个更具可读性的版本,添加了所有格量词,以挤出更多的速度:

{{\#每个\s+(\w+)\s+as\s+(\w+)\s*}
(?:(?!{{[#/]各\b)*+
(?:
(?R)
(?:(?!{{[#/]各\b)*+
)*+
{{/每个}}

[^()]*
在您链接到的正则表达式中,不表示前导边界或尾随边界。因此,您需要这样的东西。谢谢@WiktorStribiżew!这正是我想要的。
[^()]*
在您链接到的正则表达式中,它不表示前导边界或尾随边界。因此,您需要这样的东西。谢谢@WiktorStribiżew!这正符合我的要求。哇,答案太棒了,我想我不会轻易发现这一点。它在我的应用程序中工作。我需要一点时间才能理解它的工作原理,但是您的answer是一个很好的资源。多亏了你和Wiktor!哇,答案太棒了,我想我不会轻易发现这个。它在我的应用程序中工作。我需要一点时间来理解它是如何工作的,但你的答案是一个很好的资源。多亏了你和Wiktor!