За последние 24 часа нас посетили 54039 программистов и 1733 робота. Сейчас ищут 795 программистов ...

Регулярка для разбора комментария

Тема в разделе "PHP для новичков", создана пользователем Yankovitz, 9 июл 2018.

  1. Yankovitz

    Yankovitz Активный пользователь

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Есть комментарий к функции:
    Код (Text):
    1. /**
    2. * This is simple function
    3. *
    4. * This is big description
    5. * of current function
    6. *
    7. * @category   CategoryName
    8. * @author     Original Author <author@example.com>
    9. * @author     Another Author <another@example.com>
    10. * @copyright  1997-2005 The PHP Group
    11. * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
    12. * @link       http://pear.php.net/package/PackageName
    13. * @see        NetOther, Net_Sample::Net_Sample()
    14. * @since      File available since Release 1.2.0
    15. * @deprecated File deprecated in Release 2.0.0
    16. */
    Необходимо разобрать на массив весь комментарий, где параметры начинающиеся с @ - должны выглядеть так:
    Код (Text):
    1. array(
    2.    'category' => 'CategoryName',
    3.    'author' => array( 'Another Author <another@example.com>', 'Original Author <author@example.com>' ),
    4. );
    Думаю о регулярках. Может кто-то видел готовые парсеры?
     
  2. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Можно и так, а можно вообще без единого регулярного выражения. Вы бы показали то, что уже пытались сделать сами.
     
  3. Yankovitz

    Yankovitz Активный пользователь

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Использую такую регулярку:
    preg_match( "(?<=[\s])[$@\w\s]*(?=[\s"])", $el, $m )
    Но пока не сдвинулось с точки
     
  4. Yankovitz

    Yankovitz Активный пользователь

    С нами с:
    21 ноя 2014
    Сообщения:
    194
    Симпатии:
    6
    Получилось как-то так:
    Код (Text):
    1.             $results = array();
    2.             $segments = explode( '*', $fn_data['comment'] );
    3.             foreach($segments as $segment) {
    4.                 // Strip trailing/leading whitespace and line breaks
    5.                 $segment = trim( $segment, '/' );
    6.                 $segment = trim( $segment );
    7.  
    8.                 if ( $segment[0] !== "@" && $segment[0] !== "" ) {
    9.                     // Description of function
    10.                     $results['desc'] .= $segment . ' ';
    11.                 } elseif ( $segment[0] === "@" ) {
    12.                     $el = explode( ' ', $segment );
    13.                    
    14.                     // Find the first space, usually after @xxxx text
    15.                     $pos = strpos( ' ', $segment );
    16.                     // rest of the string
    17.                     $value = substr( $segment, $pos+1 );
    18.                     $name = str_replace( '@', '', $el[0] );
    19.                    
    20.                     $results[$name] = trim( str_replace( $name, '', $value ) );
    21.                 }
    22.             }
    Из этого:
    Код (Text):
    1. /**
    2. * This is simple function.
    3. *
    4. * This is big description
    5. * of current function.
    6. *
    7. * @category   CategoryName
    8. * @package    PackageName
    9. * @author     Original Author <author@example.com>
    10. * @author     Another Author <another@example.com>
    11. * @copyright  1997-2005 The PHP Group
    12. * @license    http://www.php.net/license/3_01.txt  PHP License 3.01
    13. * @version    SVN: $Id$
    14. * @param      String|Int параметр1
    15. * @param      Array параметр2
    16. * @link       http://pear.php.net/package/PackageName
    17. * @see        NetOther, Net_Sample::Net_Sample()
    18. * @since      File available since Release 1.2.0
    19. * @deprecated File deprecated in Release 2.0.0
    20. */
    Получается это:
    Код (Text):
    1. Array
    2. (
    3.     [desc] => This is simple function. This is big description of current function.
    4.     [category] => CategoryName
    5.     [package] => PackageName
    6.     [author] => Another Author
    7.     [copyright] => 1997-2005 The PHP Group
    8.     [license] => http://www.php.net//3_01.txt  PHP License 3.01
    9.     [version] => SVN: $Id$
    10.     [param] => Array параметр2
    11.     [link] => http://pear.php.net/package/PackageName
    12.     [see] => NetOther, Net_Sample::Net_Sample()
    13.     [since] => File available  Release 1.2.0
    14.     [deprecated] => File  in Release 2.0.0
    15. )
     
  5. Deonis

    Deonis Старожил

    С нами с:
    15 фев 2013
    Сообщения:
    1.521
    Симпатии:
    504
    Близко. Если идти по вашему пути, то код можно доработать таким образом (результат в песочнице):
    PHP:
    1. <?php
    2. $results = [
    3.     'descr' => []
    4. ];
    5.  
    6. $segments = explode('*', $str);
    7. foreach($segments as $segment) {
    8.     if(($segment = trim($segment, '/ '.PHP_EOL)) != '') {
    9.         if(strpos($segment, '@') === 0) {
    10.             $p = strpos($segment, ' ');
    11.             $results[trim(substr($segment, 0, $p), '@')][] = trim(substr($segment, $p));
    12.         } else {
    13.             $results['descr'][] = $segment;
    14.         }
    15.     }
    16. }
    17. $results['descr'] = implode(' ', $results['descr']);
    18. print_r($results);
    --- Добавлено ---
    P.S. Т.к. могут быть дескрипторы без значений, 10-ую строку можно изменить:
    PHP:
    1. // Вместо
    2. $p = strpos($segment, ' ');
    3. // Пишем
    4. $p = ($p = strpos($segment, ' ')) ? $p : strlen($segment);