【发布时间】:2010-11-14 10:32:36
【问题描述】:
我一直在尝试使用正则表达式匹配 PHP cmets。
//([^<]+)\r\n
这就是我得到的,但它并没有真正起作用。
我也试过
//([^<]+)\r
//([^<]+)\n
//([^<]+)
……没用
【问题讨论】:
-
可以提供更多关于您想要实现的目标的信息,您要匹配的语言是什么来自。
我一直在尝试使用正则表达式匹配 PHP cmets。
//([^<]+)\r\n
这就是我得到的,但它并没有真正起作用。
我也试过
//([^<]+)\r
//([^<]+)\n
//([^<]+)
……没用
【问题讨论】:
这将匹配 PHP 中的 cmets(/* */ 和 // 格式)
/(\/\*).*?(\*\/)|(\/\/).*?(\n)/s
要获取所有匹配项,请使用 preg_match_all 获取匹配项数组。
【讨论】:
要匹配 cmets,你必须认为 PHP 5 中有两种类型的 cmets:
//开头并到行尾的cmets/* 开头并转到*/ 的cmets
首先考虑到这两行:
$filePath = '/home/squale/developpement/astralblog/website/library/HTMLPurifier.php';
$str = file_get_contents($filePath);
您可以将第一个匹配为:
$matches_slashslash = array();
if (preg_match_all('#//(.*)$#m', $str, $matches_slashslash)) {
var_dump($matches_slashslash[1]);
}
第二个是:
$matches_slashstar = array();
if (preg_match_all('#/\*(.*?)\*/#sm', $str, $matches_slashstar)) {
var_dump($matches_slashstar[1]);
}
但是你可能会在字符串(what about heredoc syntax, btw, did you think about that one ? ) 中间出现'//',或者像这样的“toggle cmets”:
/*
echo 'a';
/*/
echo 'b';
//*/
(如果你不知道诀窍,只需在开头添加一个斜线以“切换”两个块)
所以... 仅使用正则表达式很难检测 cmets...
另一种方法是使用 PHP Tokenizer,它显然知道如何解析 PHP 代码和 cmets。
有关参考,请参阅:
这样,您将不得不在您的 PHP 代码字符串上使用标记器,迭代您获得的所有标记,并检测哪些是 cmets。
这样的事情可能会做:
$tokens = token_get_all($str);
foreach ($tokens as $token) {
if ($token[0] == T_COMMENT
|| $token[0] == T_DOC_COMMENT) {
// This is a comment ;-)
var_dump($token);
}
}
而且,作为输出,你会得到一个这样的列表:
array
0 => int 366
1 => string '/** Version of HTML Purifier */' (length=31)
2 => int 57
或者这个:
array
0 => int 365
1 => string '// :TODO: make the config merge in, instead of replace
' (length=55)
2 => int 117
(您“只是”可能会剥离 // 和 /* */,但这取决于您;至少,您已经提取了 cmets ^^)
如果你真的想检测 cmets 而不会因为“奇怪”的语法而出现任何奇怪的错误,我想这就是要走的路 ;-)
【讨论】:
您在哪个程序中编写此正则表达式?如果您担心换行符不起作用,您的最后一个示例是一个很好的完整性检查。 (我不知道您为什么不允许在您的评论中使用小于;我假设这是特定于您的应用程序的。)
试试
//[^<]+
看看这是否有效。正如 Draemon 所说,你可能不得不逃离对角线。您可能还必须转义括号。我不知道你是否知道这一点,但括号通常用于括起来捕获组。最后,检查双斜杠后是否确实至少有一个字符。
【讨论】:
您可能需要转义“//”:
\/\/([^<]+)
【讨论】: