25

我想解析一个文件,我想使用 php 和 regex 来剥离:

  • 空行或空行
  • 单行注释
  • 多行注释

基本上我想删除任何包含

/* text */ 

或多行注释

/***
some
text
*****/

如果可能,另一个正则表达式来检查该行是否为空(删除空行)

那可能吗?有人可以向我发布一个正则表达式吗?

非常感谢。

4

9 回答 9

48
$text = preg_replace('!/\*.*?\*/!s', '', $text);
$text = preg_replace('/\n\s*\n/', "\n", $text);
于 2009-03-13T15:05:22.877 回答
12

请记住,如果您正在解析的文件的字符串包含与这些条件匹配的内容,那么您使用的任何正则表达式都将失败。例如,它会变成这样:

print "/* a comment */";

进入这个:

print "";

这可能不是你想要的。但也许是,我不知道。无论如何,正则表达式在技术上无法以某种方式解析数据以避免该问题。我说技术上是因为现代 PCRE 正则表达式已经添加了许多技巧,使它们都能够做到这一点,更重要的是,不再是正则表达式,而是其他的。如果您想避免在引号内或在其他情况下剥离这些内容,则无法替代成熟的解析器(尽管它仍然可以很简单)。

于 2009-03-13T15:11:01.443 回答
7
//  Removes multi-line comments and does not create
//  a blank line, also treats white spaces/tabs 
$text = preg_replace('!^[ \t]*/\*.*?\*/[ \t]*[\r\n]!s', '', $text);

//  Removes single line '//' comments, treats blank characters
$text = preg_replace('![ \t]*//.*[ \t]*[\r\n]!', '', $text);

//  Strip blank lines
$text = preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/", "\n", $text);
于 2013-10-02T12:15:40.257 回答
3
$string = preg_replace('#/\*[^*]*\*+([^/][^*]*\*+)*/#', '', $string);
于 2012-02-03T15:06:17.777 回答
2

可能的,但我不会这样做。您需要解析整个 php 文件以确保您没有删除任何必要的空格(字符串、关键字/标识符之间的空格(publicfuntiondoStuff())等)。更好地使用 PHP 的tokenizer 扩展

于 2009-03-13T15:12:48.490 回答
2

这应该可以将所有 /* 替换为 */。

$string = preg_replace('/(\s+)\/\*([^\/]*)\*\/(\s+)/s', "\n", $string);
于 2009-03-13T15:28:10.620 回答
1

这是一个很好的功能,而且有效!

<?
if (!defined('T_ML_COMMENT')) {
   define('T_ML_COMMENT', T_COMMENT);
} else {
   define('T_DOC_COMMENT', T_ML_COMMENT);
}
function strip_comments($source) {
    $tokens = token_get_all($source);
    $ret = "";
    foreach ($tokens as $token) {
       if (is_string($token)) {
          $ret.= $token;
       } else {
          list($id, $text) = $token;

          switch ($id) { 
             case T_COMMENT: 
             case T_ML_COMMENT: // we've defined this
             case T_DOC_COMMENT: // and this
                break;

             default:
                $ret.= $text;
                break;
          }
       }
    }    
    return trim(str_replace(array('<?','?>'),array('',''),$ret));
}
?>

现在使用这个函数'strip_comments'来传递包含在某个变量中的代码:

<?
$code = "
<?php 
    /* this is comment */
   // this is also a comment
   # me too, am also comment
   echo "And I am some code...";
?>";

$code = strip_comments($code);

echo htmlspecialchars($code);
?>

将结果输出为

<?
echo "And I am some code...";
?>

从 php 文件加载:

<?
$code = file_get_contents("some_code_file.php");
$code = strip_comments($code);

echo htmlspecialchars($code);
?>

加载一个 php 文件,剥离注释并将其保存回来

<?
$file = "some_code_file.php"
$code = file_get_contents($file);
$code = strip_comments($code);

$f = fopen($file,"w");
fwrite($f,$code);
fclose($f);
?>

来源:http ://www.php.net/manual/en/tokenizer.examples.php

于 2012-10-04T18:59:06.653 回答
0

这是我的解决方案,如果不习惯正则表达式。以下代码删除所有由 # 分隔的注释,并以这种样式 NAME=VALUE 检索变量的值

  $reg = array();
  $handle = @fopen("/etc/chilli/config", "r");
  if ($handle) {
   while (($buffer = fgets($handle, 4096)) !== false) {
    $start = strpos($buffer,"#") ;
    $end   = strpos($buffer,"\n");
     // echo $start.",".$end;
       // echo $buffer ."<br>";



     if ($start !== false)

        $res = substr($buffer,0,$start);
    else
        $res = $buffer; 
        $a = explode("=",$res);

        if (count($a)>0)
        {
            if (count($a) == 1 && !empty($a[0]) && trim($a[0])!="")
                $reg[ $a[0] ] = "";
            else
            {
                if (!empty($a[0]) && trim($a[0])!="")
                    $reg[ $a[0] ] = $a[1];
            }
        }




    }

    if (!feof($handle)) {
        echo "Error: unexpected fgets() fail\n";
    }
    fclose($handle);
}
于 2012-05-31T16:59:28.207 回答
0

我发现这个更适合我,(\s+)\/\*([^\/]*)\*/\n*它删除了多行、标签或不注释以及它后面的间隔。我将留下这个正则表达式匹配的评论示例。

/**
 * The AdditionalCategory
 * Meta informations extracted from the WSDL
 * - minOccurs : 0
 * - nillable : true
 * @var TestStructAdditionalCategorizationExternalIntegrationCUDListDataContract
 */
于 2019-05-24T08:39:04.963 回答