Regex to remove comments PHP.

Тема в разделе "Регулярные выражения", создана пользователем lag, 23 май 2015.

Статус темы:
Закрыта.
Модераторы: xpert13
  1. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    188
    Симпатии:
    227
    Размышлял над регулярным выражением для удаления комментариев из 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$matchPREG_OFFSET_CAPTURE) )
            return 
    $src;

        return 
    substr($src0$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  >

    <!-- *//* -->
     
    Последнее редактирование: 23 май 2015
    latteo нравится это.
  2. xpert13

    xpert13 <(*_*)>

    Moderator
    Регистр.:
    7 ноя 2008
    Сообщения:
    182
    Симпатии:
    453
    Вы бы лучше дали текст, на котором можно тестировать регулярку.
     
  3. lag

    lag

    Регистр.:
    13 окт 2014
    Сообщения:
    188
    Симпатии:
    227
    Новую версию регулярки можно потестить тут https://regex101.com/r/uN1yP6/1
    Теперь короткие теги <? игнорируются, работает только с <?php, <?=, <script language="php"> </script>
     
  4. BaBL

    BaBL Постоялец

    Регистр.:
    13 ноя 2012
    Сообщения:
    144
    Симпатии:
    87
    xpert13 и latteo нравится это.
Статус темы:
Закрыта.