2013-08-05 2 views

ответ

6

На самом деле Perl интерпретирует \111 как восьмеричный элемент, который не найден в вашей строке . Он учитывал бы только две или более цифр обратных ссылок, если найдено такое количество . Чтобы избежать двусмысленности, используйте \g или \g{}. Цитирование Документов (perlre - Capture Groups):

Параметр \ г и \ к нотации были введены в Perl 5.10.0. До этого не были названы и относительными пронумерованными группами захвата. Абсолютные нумерованные группы упоминались с использованием \ 1, \ 2 и т. Д., И эта нотация все еще принимается (и, вероятно, всегда будет). Но это приводит к некоторым двусмысленностям, если есть более 9 групп захвата, так как \ 10 может означать либо десятую группу захвата , либо символ, порядковый номер которого равен восьмеричному 010 (обратное пространство в ASCII). Perl разрешает эту двусмысленность, интерпретируя \ 10 как обратную ссылку , только если перед ней открылось не менее 10 левых круглых скобок. Аналогично, \ 11 - , только если в нем открылось не менее 11 левых круглых скобок. И так далее. От 1 до 9 всегда интерпретируются как обратные ссылки. Существует несколько примеров, иллюстрирующих эти опасности. Вы можете избежать двусмысленности , всегда используя \ g {} или \ g, если вы имеете в виду группы захвата; и для восьмеричные константы всегда используют \ o {} или для \ 077 и ниже, используя 3 цифры , заполненные ведущими нулями, поскольку начальный нуль подразумевает восьмеричную константу.

+0

Я прочитал документацию, но это не совсем понятно для меня. Если '\ 111' интерпретируется как восьмеричный, то' \ 11' должен работать, а это не так. А также '\ 001' должен работать, потому что это восьмеричное число первых обратных ссылок, и оно не совпадает. Что я упустил? – Birei

+1

@Birei Это восьмеричный * символ * ссылка на символ '0111' = символ 73 =' "I" '. Таким образом, ваш шаблон соответствует любому символу, за которым следует буква I. – hobbs

+0

@hobbs: Спасибо. Я уже понял этот момент, но как насчет '\ 11'? – Birei

5

Это лечения \111 как один элемент, потому что нет ничего отделения \1 от 11. Если вы используете модификатор /x, чтобы интервал можно удалить двусмысленность:

if(/(.)\1 11/x) { ... 
+1

или 'if (/ (.) \ G {1} 11 /)' – chilemagic

+1

@Matt, который будет работать только в perls 5.10 или выше. Многие из нас застряли в 5.8.8. – AKHolland

+0

Да, ты прав, хороший звонок. У нас есть здесь здесь для справки :) Я уверен, что Perl 5.8.8 по умолчанию используется в Red Hat 5, который поддерживается до 2017 года (или что-то еще), поэтому у нас может быть много программистов, застрявших там некоторое время. – chilemagic