在全局多行模式下使用 RegEx 仅匹配 PHP 代码 (/gm)
Match Only PHP Code Using RegEx In Global MultiLine Mode (/gm)
我试图仅匹配 PHP 代码,例如此块中的 php 代码:
<?php foo(); ?>
<abc>
<? foo(); ?>
<?php
foo();
bar();
?>
foo();
bar();
<? //also short open tag
foo();
bar();
?><?php
foo();
bar();
我希望它只匹配 php 标签之间的代码,包括带结束标签的 php 开始标签和不包括结束标签的仅 php 开始标签(可以发生在 php 代码的最后。
我尝试了很多正则表达式选项,最后得到了这个,但它显然不能像我想要的那样工作,因为它处于 /g
模式,并且还选择了 <abc>
而它应该't (Demo):
<\?.*[\s\S]*?(?:$|\?\>)
有什么方法可以在 /gm
模式下使用正则表达式实现此目的吗?
请注意,我问的原因是因为我正在使用文件搜索程序,当我搜索我拥有的许多 php 文件的内容时,我希望它只在 php 代码,而不是得出不相关的结果。因此,我将使用此正则表达式作为其余内容搜索的附加条件。搜索程序使用PCRE /gm
模式。
P.S。在发布问题之前,我对 SO 做了很多研究,但找不到解决这个问题的方法。
除其他问题外,我还检查了:
My regex is matching too much. How do I make it stop?
Get content between two strings PHP
结论
我最终使用了 Julio 的解决方案并对其进行了改进,以考虑到 Jan 的回答示例中提到的单引号和双引号。谢谢大家的答案。
这是在 /gm
模式下工作的最终正则表达式:
<\?[\s\S]*?(?:\z|\?\>|[\"\'].*?[\"\'][\s\S]*?\?>)
使用这个:<\?[\s\S]*?(?:\z|\?\>)
.*[\s\S]*
是多余的。你只需要 [\s\S]*
来匹配任何字符(另外,由于 .*
是贪婪的,它匹配你的结尾 ?>
)
也使用 \z
代替 $
这应该适合你:
(<\?)(.*?)(?:$|\?>)/isg
你可以使用
<\?(?:php)? # <? or <?php
(?:(?!\?>)[\s\S])* # do not overrun ?> but match anything else greedily
(?:\?>)? # ?> in the end
参见 a demo on regex101.com(注意冗长的标志!)。
让我强调一下,这通常是一个糟糕的方法,例如。字符串如
<?php
echo "This is hilarious ?>";
?>
另见 demo for the latter on regex101.com。在这里,改用解析器或重新考虑您原来的问题。
我试图仅匹配 PHP 代码,例如此块中的 php 代码:
<?php foo(); ?>
<abc>
<? foo(); ?>
<?php
foo();
bar();
?>
foo();
bar();
<? //also short open tag
foo();
bar();
?><?php
foo();
bar();
我希望它只匹配 php 标签之间的代码,包括带结束标签的 php 开始标签和不包括结束标签的仅 php 开始标签(可以发生在 php 代码的最后。
我尝试了很多正则表达式选项,最后得到了这个,但它显然不能像我想要的那样工作,因为它处于 /g
模式,并且还选择了 <abc>
而它应该't (Demo):
<\?.*[\s\S]*?(?:$|\?\>)
有什么方法可以在 /gm
模式下使用正则表达式实现此目的吗?
请注意,我问的原因是因为我正在使用文件搜索程序,当我搜索我拥有的许多 php 文件的内容时,我希望它只在 php 代码,而不是得出不相关的结果。因此,我将使用此正则表达式作为其余内容搜索的附加条件。搜索程序使用PCRE /gm
模式。
P.S。在发布问题之前,我对 SO 做了很多研究,但找不到解决这个问题的方法。 除其他问题外,我还检查了:
My regex is matching too much. How do I make it stop?
Get content between two strings PHP
结论
我最终使用了 Julio 的解决方案并对其进行了改进,以考虑到 Jan 的回答示例中提到的单引号和双引号。谢谢大家的答案。
这是在 /gm
模式下工作的最终正则表达式:
<\?[\s\S]*?(?:\z|\?\>|[\"\'].*?[\"\'][\s\S]*?\?>)
使用这个:<\?[\s\S]*?(?:\z|\?\>)
.*[\s\S]*
是多余的。你只需要 [\s\S]*
来匹配任何字符(另外,由于 .*
是贪婪的,它匹配你的结尾 ?>
)
也使用 \z
代替 $
这应该适合你:
(<\?)(.*?)(?:$|\?>)/isg
你可以使用
<\?(?:php)? # <? or <?php
(?:(?!\?>)[\s\S])* # do not overrun ?> but match anything else greedily
(?:\?>)? # ?> in the end
参见 a demo on regex101.com(注意冗长的标志!)。
让我强调一下,这通常是一个糟糕的方法,例如。字符串如
<?php
echo "This is hilarious ?>";
?>
另见 demo for the latter on regex101.com。在这里,改用解析器或重新考虑您原来的问题。