Xpoint
   [напомнить пароль]

Программирование::Perl::Регулярные выражения - F.A.Q.

Совет как сделать правильную проверку введенного e-mail.
Как должны выглядеть адреса: rfc 822, 2822
Модули: RFC::RFC822::Address, Email::Valid
Регулярное выражение: тут, тут

Как могут выглядеть адреса (если вы захотели написать свое выражение):

  • a%b.c@d.e # сначала письмо идет на d.e, затем на a@b.c
  • a+b@c.d # адрес a@c.d, b - некий комментарий.
  • a::b@c.d # mail11 (для vms) нотация.
  • b!d # uucp нотация
  • @a.b;c@d.e # gateway нотация
Как заменить несколько значений в строке на несколько других значений одним махом? есть строка, в которй есть куча(!) значений, к примеру есть aa,bb,cc,dd их надо одной строкой заменить на переменные $aa,$bb,$cc,$dd
  • s/(aa|bb|cc|dd)/\$$1/g; # Заменяет aa -> $aa etc литерально
  • s/(aa|bb|cc|dd)/${$1}/g; # Заменяет aa на значение переменной $aa etc.
Литература по регулярным выражениям.
  • Jeffrey E.F. Friedl. Mastering Regular Expressions (есть русское издание). O'Reilly&Associates, Inc. Весьма рекомендую (arto)
  • regexp.ru
  • perldoc perlre
  • perldoc perlretut
  • Есть раздел в Advanced Perl Programming (тоже O'Reilly). Весьма качественная книга для дальнейшего изучения языка (arto)
Отрицание в регулярных выражениях
perldoc perlre на предмет "A zero-width negative lookahead assertion" и тому подобное.
Замена всех спецсимволов на \спецсимвол
  • s/(["'`\\])/\\$1/sg (Kukoyasnei Ruslan)
  • s/(?=["'`\\])/\\/sg (Дмитрий Котеров)
Работа с переносами строки.
Символ переноса строки может быть один "\n", или два "\r\n". В обоих случаях это есть перенос строки. В unix системах используется \n, в win \r\n. И так. Перенос можно убить:
s/\r?\n//g;
или заменить на другой символ или последовательность символов:
s/\r?\n/<br \/>/g
в данном случае меняем на перевод строки в HTML.
Поиск URL в тексте и далнейшее подсвечивание таковых, непосредственно, ссылками.
  • Пример: В тексте встречается фрагмент: http://www.server.ru, заменить его надо на <a href="http://www.server.ru/>http://www.server.ru/</a>
  • Варианты решений:
    1.
    s[((?:ht|f)tp://(?:[\w\-]+\.)+\w+(?:\:\d+)?(?:/[\w\.\~,\-/]*(?:\?[\w;% \+\-,\=\&]+)?(?:\*)?)?)][\<a href="$1">$1\</a>]goi;
    (Андрей Новиков)
    2.
    s/\b((ht|f)tp):(\/\/)([a-z0-9.:@*()~#\]\[_?=&\/\\-])+/<a href=$&>$&<\/a>/gi;
    (Михаил Кюршин)
    3.
    s|(http://[^\s]+)|<a href=$1>$1</a>|ig;
    (Михаил Костиков)
  • Как вы понимаете, возможны и другие варианты. Это лишь примеры.
    Как добиться нормального понимания русских букв в регулярном выражении при использовании модификаторов (/i) или спецсимволов (\w или \W) по отношению к тексту.
    Для нормального восприятия текста в кодировке windows-1251 в скрипте следует прописать следующее:

    use locale; use POSIX qw(locale_h); setlocale(LC_CTYPE,"ru_RU.CP1251");

    Правда следует отметить, что соответствущая кодировка должна пониматься самой операционной системой.

    См. так же:
      perldoc locale
      perldoc perllocale
      Поддержка Unicode
    Что лучше использовать - $1 или $&?

    Автор ответа - Виктор Ганский

    Проблема:

    Если в программе или в любом подключаемом ей модуле есть хоть одно упоминание о $&, $` или $', то для каждого успешного совпадения регулярного выражения Perl будет заполнять эти переменные, что, мягко говоря, иногда очень ресурсоемко.

    Вдобавок, использование переменных этого семейства подавляет некоторые оптимизации при заменах.

    Вердикт:

    Полностью исключить использование этих переменных и модулей их содержащих.

    Альтернативы:
    $& - заключить все выражение в ()
    $` - (.*?) перед выражением
    $' - (?=(.*)) после выражения

    И использовать $1-$9.

    Пример:

        $str = '1'x1000000;
        $str =~ /1/;
        $str = 'abc';    # Эту строку можно убрать
        $str =~ /a/;     # Эту строку можно убрать
        $';
    

    После первого регулярного выражения для переменной $' резервируется дополнительный мегабайт в памяти. Теперь, этот мегабайт так и останется зарезервированным независимо от того, что логически, после второго регулярного выражения "длина" $' будет только 2 байта.

    Powered by POEM™ Engine Copyright © 2002-2005