Php 如何通过regexp剥离MySQL的可执行注释

Php 如何通过regexp剥离MySQL的可执行注释,php,regex,strip,Php,Regex,Strip,我需要在mysqldump结果中获取可执行注释的内容,但对于regexp /\/\*\!\d+\s+(.*?)\*\//s 并输入如下数据: /*!50003 text some text else /* comment also comment */ text... and also text... */ 我得到了错误的结果,因为它只从“文本”到“注释”行获取数据。如何将注释跳过到注释中? 谢谢 UPD:我不能使用“^”和“$”来标记输入的开始和结束,因为我在输入中有很多可执行语句 UPD

我需要在mysqldump结果中获取可执行注释的内容,但对于regexp

/\/\*\!\d+\s+(.*?)\*\//s
并输入如下数据:

/*!50003 text
some text else
/*
comment
also comment
*/
text...
and also text...
*/
我得到了错误的结果,因为它只从“文本”到“注释”行获取数据。如何将注释跳过到注释中? 谢谢

UPD:我不能使用“^”和“$”来标记输入的开始和结束,因为我在输入中有很多可执行语句

UPD2:我想要的输出:

text
some text else
/*
comment
also comment
*/
text...
and also text...
并非所有的输入方式都在下面的注释中。我想,这很奇怪,得到的输出和输入是一样的

UPD3
可执行注释的开头必须是/*!任何数字。必须跳过它,并且不包括在输出中。“UPD2”中给出了可执行文件结尾注释*/右输出示例。

纯正则表达式无法处理嵌套,但PHP的风格可以通过使用。使用,以便我们可以使用空格和注释:

%(#打开重新分隔符,组开始
/\*#注释打开标记
([^/*]#非注释标记字符
|/(?!\*)#“/”后面没有“*”,因此没有打开评论
|\*(?!/)\\'*'后面没有“/”,因此不是结束评论
|(?R)#递归情况
)*#重复任意次数
\*/#注释结束标记
)%x#组结束,结束符重新分隔符,PCRE#U扩展
简言之:

%(/\*([^/*]\/(?!\*)\*(?!/)\*(?!/)\*(?R))*\*/)%x
使用中:

<?php

$commentRE = '%(/\*([^/*]|/(?!\*)|\*(?!/)|(?1))*\*/)%';
$doc = <<<EOS

USE database;

/* comment
and a
/* nested comment /* me too */
   now exiting
 */
the comment */


/*!50003 text
some text else
/*
comment
also comment
*/
text...
and also text...
*/

CREATE TABLE IF NOT EXISTS ...

EOS;

preg_match_all($commentRE, $doc, $parts);
var_export($parts[0]);

纯正则表达式不能处理嵌套,但是PHP的风格可以通过使用。使用,以便我们可以使用空格和注释:

%(#打开重新分隔符,组开始
/\*#注释打开标记
([^/*]#非注释标记字符
|/(?!\*)#“/”后面没有“*”,因此没有打开评论
|\*(?!/)\\'*'后面没有“/”,因此不是结束评论
|(?R)#递归情况
)*#重复任意次数
\*/#注释结束标记
)%x#组结束,结束符重新分隔符,PCRE#U扩展
简言之:

%(/\*([^/*]\/(?!\*)\*(?!/)\*(?!/)\*(?R))*\*/)%x
使用中:

<?php

$commentRE = '%(/\*([^/*]|/(?!\*)|\*(?!/)|(?1))*\*/)%';
$doc = <<<EOS

USE database;

/* comment
and a
/* nested comment /* me too */
   now exiting
 */
the comment */


/*!50003 text
some text else
/*
comment
also comment
*/
text...
and also text...
*/

CREATE TABLE IF NOT EXISTS ...

EOS;

preg_match_all($commentRE, $doc, $parts);
var_export($parts[0]);

基于这一出色的解决方案,我使用PHP regexp删除了所有类型的注释(并且只删除注释,而不是类似注释的引用文本;):

基于这个优秀的解决方案,我使用PHP regexp删除了所有类型的注释(并且只删除注释,而不是类似注释的引用文本;):

是否要为所有注释“展开”最外层的注释,剥离注释的某些部分,还是只对以特定模式开头的注释执行此操作?第一部分的确切模式是什么?到底是“!50003文本”,还是数字可以是任何东西?“文本”部分的确切模式是什么?是一个单词吗?直到新的生产线?问题是什么?当然,我问的是“常见”问题,而不是“50003”硬编码的情况。您是要为所有注释“展开”最外层的注释,剥离注释的某些部分,还是只对以特定模式开头的注释执行此操作?第一部分的确切模式是什么?到底是“!50003文本”,还是数字可以是任何东西?“文本”部分的确切模式是什么?是一个单词吗?直到新的生产线?问题是什么?当然,我问的是“常见”问题,而不是“!50003”硬编码的情况。