我有以下 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?((\(.*?\)|.)*?)\)
回答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
:第一组内容