如何匹配它们之间的所有php标记对和内容。
我使用这个正则表达式:/<\?.*\?>(?=[^'])/mgs
,我的文字是
<? $b = '?>';$c = '';$d = '';$e = '';$a = 1;?><div><? $a = 1; ?>`
我的正则表达式只给了我第一场比赛<? $b = '?>';$c = '';$d = '';$e = '';$a = 1;?>
实际的PHP代码:
$matches = [];
$str = '<? $b = \'?>\';
$c = \'\';$d = \'\';$e = \'\';
$a = 1;?><div><? ?>';
preg_match_all('/<\?.*\?>(?=[^\'])/sm', $str, $matches);
print_r($matches);
答案 0 :(得分:0)
我的第一个想法是使用tokenizer,但经过一些测试后,似乎这个人无法识别短开的php标签<?
。
我决定编写一个描述两个陷阱的模式:注释和字符串。
$str = <<<'EOD'
<? $b = '?>';
$c = '';$d = '';$e = '';
$a = 1;?><div><? ?>';
EOD;
$pattern = <<<'EOD'
~
# subpatterns definitions
(?(DEFINE)
(?<sqs> # single quote string
' [^'\\]*+ (?s: \\. [^'\\]* )*+ '
)
(?<dqs> # double quote string
" [^"\\]*+ (?s: \\. [^"\\]* )*+ "
)
(?<identifier> [a-zA-Z_][a-zA-Z0-9_]* )
(?<hds> # heredoc string
<<< (?| \g<identifier> | " ( \g<identifier> ) " ) \R
(?: .* \R )*?
\g{-1} ;? \R
)
(?<nds> # nowdoc string
<<< '( \g<identifier> )' \R
(?: .* \R )*?
\g{-1} ;? \R
)
(?<str> \g<sqs> | \g<dqs> | \g<hds> | \g<nds> )
(?<slc> // .* ) # singleline comment
(?<mlc> /\* [^*]*+ (?: \* (?!/) [^*]* )*+ (?:\*/)? ) # multiline comment
(?<comment> \g<slc> | \g<mlc> )
)
# main pattern
<\? (?:php)? \s
(?<content>
[^</"'?]*+
(?:
\g<comment> [^</"'?]*
|
\g<str> [^</"'?]*
|
< [^</"'?]*
|
\? (?!>) [^</"'?]*
)*+
)
(?: \?> )?
~x
EOD;
if ( preg_match_all($pattern, $str, $matches) )
print_r($matches['content']);