Комментирование регулярных выражений

Проблема

Требуется сделать ваше сложное регулярное выражение более понятным и упростить его изменение в будущем.

Решение

В вашем распоряжении четыре способа: внешние комментарии, внутренние комментарии с модификатором /х, внутренние комментарии в заменяющей части s/// и альтернативные ограничители.

Комментарий

В следующем фрагменте использованы все четыре способа. Начальный комментарий описывает, для чего предназначено регулярное выражение. Для относительно простых шаблонов ничего больше не потребуется. В сложных шаблонах (вроде приведенного) желательно привести дополнительные комментарии.
# resname - заменить все имена в стиле "foo.bar.com" во входном потоке
# на "foo.bar.com [204.148.40.9]" (или аналогичными)
use Socket;                           # Загрузить inet_addr
s{                                    #
   (                                  # Сохранить имя хоста в $1
     (?:                              # Скобки только для группировки
          (?! [-_])                   # Ни подчеркивание, ни дефис
          [\w-] +                     # Компонент имени хоста
          \.                          # и точка домена
     )+                               # Повторяется несколько раз
        [A-Za-z]                      # Следующий символ должен быть буквой
        [\w-]+                        # Завершающая часть домена
   )                                  # Конец записи $1
}{                                    # Заменить следующим:
  "$1 ".                              # Исходная часть плюс пробел
    ( ($addr = gethostbyname($1))     # Если имеется адрес
      ? "[" . inet_ntoa($addr) . "]"  # отформатировать
      : "[???]"                       # иначе пометить как сомнительный
    )
}gех;                                 # /g - глобальная замена
                                      # /е - выполнение
                                      # /х - улучшенное форматирование
Для эстетов в этом примере использованы альтернативные ограничители. Когда шаблон поиска или замены растягивается на несколько строк, наличие парных скобок делает его более понятным. Другая частая причина для использования альтернативных ограничителей — присутствие в шаблоне символов / (например, S/\/\//\/..\//g). Альтернативные ограничители упрощают чтение такого шаблона (например, s!//!/../! g или s{//}{/../}g).
При наличии модификатора /х Perl игнорирует большинство пропусков в шаблоне (в символьных классах они учитываются) и интерпретирует символы и следующий за ними текст как комментарий. Такая возможность весьма полезна, однако у вас могут возникнуть проблемы, если пропуски или символы # являются частью шаблона. В таких случаях снабдите символы префиксом \, как это сделано в следующем примере:
s/              # Заменить
   \#           # знак фунта
   (\w+)        # имя переменной
   \#           # еще один знак фунта
/${$1}/хg       # значением  глобальной переменной
Помните: комментарий должен пояснять программу, а не пересказывать ее. Комментарии типа "$i++ # Увеличить $i на 1" станут причиной плохих оценок на курсах программирования или подорвут вашу репутацию среди коллег.
Остается модификатор /е, при котором заменяющая строка вычисляется как полноценное выражение Perl, а не как (заключенная в кавычки и интерполированная) строка. Результат выполнения этого кода используется в качестве заменяюшей строки. Поскольку выражение будет интерпретировано как программный код, оно может содержать комментарии. Это несколько замедляет работу программы, но не так сильно, как может показаться (пока вы не начали писать собственные тесты, желательно представлять себе эффективность тех или иных конструкций). Дело в том, что правая сторона подстановки проверяется и компилируется, на стадии компиляции вместе со всей программой. Для простой замены строк это, пожалуй, перебор, но в более сложных случаях работает просто замечательно.
Удвоение /е напоминает конструкцию eval "STRING". Это позволит применить лексические переменные вместо глобальных в предыдущем примере с заменой.
s/                  # Заменить
   \#               # знак фунта
   (\w+)            # имя переменной
   \#               # еще один знак фунта
/'$' . $1/хееg;     # значением *любой* переменной
После подстановки /ее проверьте переменную $@. Она содержит сообщения об ошибках, полученные в результате работы вашего кода, — в отличие от /е, в данном случае код действительно генерируется во время работы программы.

См. также




2013-09-10 17:05:19

Proverte kod v komentariyah gde pro list tam oshibki detskie




Оставить комментарий:
Ваше Имя:
Email:
Антибот: *  
Ваш комментарий: