regex - 捕获分隔符之间的结果。内容可能包含分隔符

我有以下 reg exp:/@\w+(\(((?:(?!\))\S|\s)*)\))?/m

我期待的 value 是模板文件,例如:

@for($i = 0; $i < 10; $i++)
    {{ $i }}
@endfor

@if(
    !empty($name)
    && $name == 'Carlos'
)
    Hi Carlos
@endif

@csfr

我无法从 @if 括号中获取完整内容。

预期结果将是:

!empty($name)
&& $name == 'Carlos'

但由于 empty 函数的右括号,它返回了这个:

!empty($name

如何捕获完整的表达式,因为这可能包含对其他函数的调用?

正则表达式调试链接:https://regex101.com/r/58ZbXe/1

回答1

您可以使用

@\w+(\(((?:[^()]++|(\g<1>))*)\))?

请参阅 https://regex101.com/r/58ZbXe/2

细节:

  • @ - @ 字符
  • \w+ - 一个或多个单词字符
  • (\(((?:[^()]++|(\g<1>))*)\))? - 第 1 组(可选):
    • \( - ( 字符
    • ((?:[^()]++|(\g<1>))*) - 第 2 组:
      • (?:[^()]++|(\g<1>))* - 零() 或第 1 组模式以外的一个或多个字符的多次重复
    • \) - ) 字符。

回答2

这是我能想到的最短的 regex :

@\w+\(((\(.*?\)|.)*?)\)

查看https://rubular.com/r/rCbZPJ3rBfog4

使用 DOTALL 标志,您的目标在组 1 中。

这通过匹配括号内的内容或括号内的点来实现。

如果您需要从 @if 内容中删除前导换行符:

@\w+\(\n?((\(.*?\)|.)*?)\)

查看https://rubular.com/r/FaODyzTrm9JRlA

回答3

试试这个 regex:

@(?<begin>[A-Za-z]+)\((?<content>[^@]*)\)[^@]+@(?<end>end\1)

解释:

  • @:@
  • (?<begin>[A-Za-z]+):第1组(开始标签)
    • [A-Za-z]+:字母字符的任意组合
  • \(:左括号
  • (?<content>[^@]*):第2组(括号内容)
    • [^@]*:@以外的任意字符
  • \):右括号
  • [^@]+:@以外的任何字符
  • @:@
  • (?<end>end\1):第三组(结束标记)
    • @:@
    • end:结束
    • \1:第一组内容

https://regex101.com/r/rwISf7/1试一试。

相似文章

c++ - 为 n-queen 问题创建回溯 Algorithm

我试图通过回溯找到解决n-queen问题的方法。我已经创建了一个板,并且我想我已经创建了检查一块是否可以放置在位置column2的函数,与位置column1的一块相比。而且我想我想以某种方式遍历列,以...