Ошибки в Perl регулярных выражениях Perl 5.12
Вот ошибки, которые я нашёл весной 2011 г. в Perl регулярных выражениях и найденные года два назад в операторах \L, \l, \U и \u,
Это - ошибка в механизме регулярных выражений, которая, после некоторых препирательств, была признана и недавно исправлена, как мне сообщили с perl.org. Я о ней написал Дж. Фридлу, всемирно известному гуру и автору книги "Регулярные выражения" (уже вышло 3-е издание), который живёт на regex.info. Он подтвердил, что это дожно быть ошибкой.
'ab' =~ /((\w+)(?{print defined $2 ? "\$2=$2\n" : "\$2 not defined\n"})){2}/; $2=ab $2 not defined $2=b
$2 not defined, хотя интуитивно кажется, что должно быть $2=a. Заменим \w+ на (?:\w|z)+ и потом на (?:\w|zz)+, получим разный вывод, хотя здесь результат работы регулярного выражения с этой строкой не должен поменяться:
'ab' =~ /(((?:\w|z)+)(?{print defined $2 ? "\$2=$2\n" : "\$2 not defined\n"})){2}/; $2=ab $2 not defined $2=b 'ab' =~ /(((?:\w|zz)+)(?{print defined $2 ? "\$2=$2\n" : "\$2 not defined\n"})){2}/; $2=ab $2=a $2=b
В последнем случае оптимизация, связанная с обработкой квантификатора +, не делается, и получается верный результат.
А эта ошибка в условном операторе:
print 'Match' if 'a' =~ /^(?(?=b)b)a$/; # Нет соответствия...
Ошибка эта, как обычно бывает с Perl, опять связана с неверной оптимизацией. Это можно установить, если данный regex слегка изменить:
print 'Match' if 'a' =~ /^(?(?=\wb)b)a$/; # Уже есть соответствие!
Добавление \w отменяет оптимизацию, и данное Perl регулярное выражение уже работает верно.
Говорят, что это исправлено в Perl 5.13.8, но последняя версия Active Perl на сегодня - это 5.12.3.
А это - найденные мной ошибки в операторах \L и \U, которые на данный момент всё ещё не исправлены. Вначале напомню, что операторы изменения регистра букв \L, \U, \l и \u работают слева направо в отличие от соответствующих им функций lc, uc, lcfirst и ucfirst. Проверим:
print "\L\udD\n"; # Dd - верно. print "\LdD\udD\n"; # Выводит dddd, а надо ddDd. Уже неверно! print "\U\La\n"; # Syntax error! Вот это да! Это должна быть только смысловая нелепица... print "\L\Ua\n"; # Syntax error! print "\L\La\n"; # Syntax error!
Глядя на подобные ошибки, думаешь: как хорошо, что Perl и Perl регулярные выражения не используются в управлении атомными электростанциями...