示例文本:https://regex101.com/r/tfYEkO/1
我想在PHP代码中找到包含空行的heredocs。
我可以使用这个正则表达式来做到这一点,但是如果文件中有2个heredoc,它会从第一个开头到第二个结尾匹配:
<<<([A-Z]+)\n.*\n\n.*\n *\1\b
所以我认为负面的前瞻会解决它,但这与任何东西都不匹配:
<<<([A-Z]+)\n(?!.*\1.*).*\n\n(?!.*\1.*).*\n *\1\b
我不认为我可以在其中使用.*
的负面观察。我尝试了ungreedy旗帜,但这似乎没有改变它。
仅供参考,php中的heredoc以<<<
和关键字开头,并以该关键字结束:
$foo = <<<HTML
This is the string that is returned.
It can contain multiple lines.
HTML;
你可以用
'~<<<([A-Za-z_]\w*)(?:\R(?!\1;\R).*)*\R(?:\R(?!\1;\R).*)*\R\1;\R~'
为了使其符合PHP 7.3 more lax requirements(现在可以缩进结束标记并删除结束标记后的新行要求),使用
'~<<<([A-Za-z_]\w*)(?:\R(?!\h*\1;$).*)*\R(?:\R(?!\h*\1;$).*)*\R\h*\1;$~m'
看另一个regex demo。
细节
<<<
- 文字的<<<
子串([A-Za-z_]\w*)
- 第1组:有效的PHP标签(必须仅包含字母数字字符和下划线,并且必须以非数字字符或下划线开头)(?:\R(?!\1;\R).*)*
- 0次或更多次换行符(\R
)没有跟随组1中的相同值,接着是;
和换行符,然后整行(.*
)\R
- 换行符(?:\R(?!\1;\R).*)*
- 见上文(请注意,如果是(?!\h*\1;$)
,则表示“未跟随0+水平空格,第1组值和;
在行尾”\R
- 换行符\1
- 与第1组中的值相同;
- 一个分号\R
- 换行符/ $
- 行的结尾(使用m
修饰符,$
匹配行结束,而不是字符串结尾)。