Regex to remove comments PHP.

Статус
В этой теме нельзя размещать новые ответы.

lag

Мой дом здесь!
Регистрация
13 Окт 2014
Сообщения
290
Реакции
366
Размышлял над регулярным выражением для удаления комментариев из PHP кода, не затрагивая содержимое строк. А строки могут быть объявлены в одинарных и двойных кавычках также может использоваться heredoc и nowdoc синтаксис. Еще могут быть строки с консольными командами в обратных кавычках.
Глядя на целый зоопарк открывающих и закрывающих тегов:
<?php ?>
<?= ?>
<? ?>
<% %>
<script language="php"> </script>
Решил ограничиться поддержкой тегов <? ?> и <script language="php"> </script>. Поддержку <% %> не добавлял.
PHP:
<!-- // -->
<?php

$lol = "*/*";

# comment
//*

if ($foo) {
  echo $bar;
}

/*/

if ($bar) {
  echo $foo;
}

// */

?>
<!-- //* -->


<script language = "php" >

# comment ?> Text <? $a = '/*'; // comment

$b = @`ls ./* -al`;

# */
</script  >

<!-- *//* -->
PHP:
<?php
$src = file_get_contents('test.php');
echo RemoveCommentsPHP($src);

function RemoveCommentsPHP($src) {
    // Поиск первого открывающего тега
    if ( !preg_match('~<(?i:\?|script\s*language\s*=\s*([\'"]?)php\1\s*>)\K~', $src, $match, PREG_OFFSET_CAPTURE) )
        return $src;

    return substr($src, 0, $match[0][1]) .
           preg_replace('~
                \G
                (?:
                    [^\'"`/#<?]+
                    |
                    \'(?:[^\'\\\\]+|\\\\.)*+\'
                    |
                    "(?:[^"\\\\]+|\\\\.)*+"
                    |
                    # остановка на // и /*
                    /(?![/*])
                    |
                    # остановка на ?>
                    \?(?!>)
                    |
                    # Строки с heredoc и nowdoc синтаксисом
                    <<<[\ \t]*([\'"]?)([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\1[\ \t]*[\r\n](?-s:.*+[\r\n])*?\2[\r\n;]  
                    |
                    # захват от закрывающих тегов ?> </script> до ближайшего открывающего
                    (?i: \?> | </script\s*> )
                    (?i:
                        [^<]+ | < (?! \? | script\s*language\s*=\s*([\'"]?)php\3\s*> )
                    )*+
                    (?: <(?:\?|[^>]+) | \Z )
                    |
                    <+
                    |
                    `(?:[^`\\\\]+|\\\\.)*+`
                )*+
                \K
                (?:
                    # однострочные комментарии // и #
                    (?://|\#)(?:[^\n?]+|\?(?!>))*+
                    |
                    # многострочные комментарии /* */
                    /\*(?:[^*]+|\*(?!/))*+\*/
                )
                ~xs', '', substr($src, $match[0][1]));
}
PHP:
<!-- // -->
<?php

$lol = "*/*";




if ($foo) {
  echo $bar;
}



?>
<!-- //* -->


<script language = "php" >

?> Text <? $a = '/*';

$b = @`ls ./* -al`;


</script  >

<!-- *//* -->
 
Последнее редактирование:
Вы бы лучше дали текст, на котором можно тестировать регулярку.
 
Новую версию регулярки можно потестить тут Для просмотра ссылки Войди или Зарегистрируйся
Теперь короткие теги <? игнорируются, работает только с <?php, <?=, <script language="php"> </script>
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху