Pergunta

Eu quero analisar um arquivo e eu quero usar php e regex para tira:

  • em branco ou vazios linhas
  • comentários de linha única
  • Multi comentários de linha

basicamente eu quero remover qualquer linha contendo

/* text */ 

ou vários linha de comentários

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

Se possível, outro regex para verificar se a linha estiver vazia (Remover as linhas em branco)

Isso é possível? Alguém pode pós-me uma regex que faz exatamente isso?

Muito obrigado.

Foi útil?

Solução

$text = preg_replace('!/\*.*?\*/!s', '', $text);
$text = preg_replace('/\n\s*\n/', "\n", $text);

Outras dicas

Tenha em mente que qualquer regex você usa falhará se o arquivo que você está de análise tem uma string contendo algo que corresponda a essas condições. Por exemplo, seria transformar este:

print "/* a comment */";

Dentro deste:

print "";

O que é provavelmente não o que você quer. Mas talvez ele é, eu não sei. De qualquer forma, Regexes tecnicamente não pode dados de análise de forma a evitar esse problema. Digo tecnicamente porque modernas expressões regulares PCRE ter pregado em uma série de hacks para torná-los tanto capaz de fazer isso e, mais importante, não mais regulares expressões, mas que seja. Se você quer evitar descascar essas coisas dentro de aspas ou em outras situações, não há substituto para um analisador de full-blown (embora ele ainda pode ser muito simples).

//  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);

é possível, mas eu não faria isso. Você precisa analisar todo o arquivo php para se certificar de que você não está removendo qualquer espaço em branco necessário (cordas, espaços em branco beween palavras-chave / identificadores (publicfuntiondoStuff ()), etc). Melhor usar a tokenizer extensão de PHP.

Isso deve funcionar em substituição de todos / * a * /.

$string = preg_replace('/(\s+)\/\*([^\/]*)\*\/(\s+)/s', "\n", $string);
$string = preg_replace('#/\*[^*]*\*+([^/][^*]*\*+)*/#', '', $string);

Esta é a minha solução, se não é usado para regexp. O código a seguir remover toda comentário delimitado por # e recupera os valores de variável nesta NOME style = VALOR

  $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);
}

Esta é uma função boa, e funciona!

<?
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));
}
?>

Agora, usando esta função 'strip_comments' para a passagem de código contido em alguma variável:

<?
$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);
?>

Será resultar saída como

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

Carregando de um arquivo PHP:

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

echo htmlspecialchars($code);
?>

Carregando um arquivo php, descascando comentários e salvá-lo de volta

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

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

Fonte: http://www.php.net/manual/en/ tokenizer.examples.php

Eu encontrei este para me adequar melhor, (\s+)\/\*([^\/]*)\*/\n* ele remove multi-linha, com guias ou não comentários e espaçadas por trás dele. Vou deixar um comentário exemplo que esse regex iria corresponder.

/**
 * The AdditionalCategory
 * Meta informations extracted from the WSDL
 * - minOccurs : 0
 * - nillable : true
 * @var TestStructAdditionalCategorizationExternalIntegrationCUDListDataContract
 */
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top