URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID8
Нить номер: 4396
[ Назад ]

Исходное сообщение
"Неадекватное поведение обратной ссылки в регулярном выражении"

Отправлено gumkins , 09-Окт-06 14:05 
Имеется следующий код:

$address = "123.221.143.167";
if ($address =~ m/(?:(\d{1,3})\.){3}\1/) {
    print "Value $address is corresponds to pattern";
} else {
    print "Neponyatka";
}

обратная ссылка "\1" в регулярном выражении должна соответствовать "\d{1,3}". Вся конструкция, следовательно, при любом значении ip-адресса в переменной $address, должна возвращать истину в операторе ветвления. Но именно тот факт, что используется обратная ссылка на подвыражение (\d{1,3}) приводит к неожиданному поведению программы. Что интересно, если взять ip-адресс 1.1.1.1 - всё работает нормально, а 1.1.1.2 - уже не проходит. Подскажите кто знает в чём загвоздка.


Содержание

Сообщения в этом обсуждении
"Неадекватное поведение обратной ссылки в регулярном выражени..."
Отправлено XAnder , 10-Окт-06 09:47 
>Имеется следующий код:
>
>$address = "123.221.143.167";
>if ($address =~ m/(?:(\d{1,3})\.){3}\1/) {
> print "Value $address is corresponds to pattern";
>} else {
> print "Neponyatka";
>}
>
>обратная ссылка "\1" в регулярном выражении должна соответствовать "\d{1,3}". Вся конструкция, следовательно,
>при любом значении ip-адресса в переменной $address, должна возвращать истину в
>операторе ветвления. Но именно тот факт, что используется обратная ссылка на
>подвыражение (\d{1,3}) приводит к неожиданному поведению программы. Что интересно, если взять
>ip-адресс 1.1.1.1 - всё работает нормально, а 1.1.1.2 - уже не
>проходит. Подскажите кто знает в чём загвоздка.

Из man perlre:

The bracketing construct "( ... )" creates capture buffers.  To refer to the digit'th buffer use \<digit> within the match.

Итак, \1 - это ссылка на буфер, в котором хранится текст, захваченный регулярным выражением в скобках. То есть на сам этот текст, а не на кусок выражения, который его захватил.

В случаях "1.1.1.1" и "1.1.1.2" \1 содержит "1", поэтому ясно, что в первом случае совпадает, а во втором - нет.


"Неадекватное поведение обратной ссылки в регулярном выражени..."
Отправлено gumkins , 10-Окт-06 14:23 
>>Имеется следующий код:
>>
>>$address = "123.221.143.167";
>>if ($address =~ m/(?:(\d{1,3})\.){3}\1/) {
>> print "Value $address is corresponds to pattern";
>>} else {
>> print "Neponyatka";
>>}
>>
>>обратная ссылка "\1" в регулярном выражении должна соответствовать "\d{1,3}". Вся конструкция, следовательно,
>>при любом значении ip-адресса в переменной $address, должна возвращать истину в
>>операторе ветвления. Но именно тот факт, что используется обратная ссылка на
>>подвыражение (\d{1,3}) приводит к неожиданному поведению программы. Что интересно, если взять
>>ip-адресс 1.1.1.1 - всё работает нормально, а 1.1.1.2 - уже не
>>проходит. Подскажите кто знает в чём загвоздка.
>
>Из man perlre:
>
>The bracketing construct "( ... )" creates capture buffers.  To refer to the digit'th buffer use \<digit> within the match.
>
>Итак, \1 - это ссылка на буфер, в котором хранится текст, захваченный
>регулярным выражением в скобках. То есть на сам этот текст, а
>не на кусок выражения, который его захватил.
>
>В случаях "1.1.1.1" и "1.1.1.2" \1 содержит "1", поэтому ясно, что в
>первом случае совпадает, а во втором - нет.

Спасибо, у меня была такая догадка. Просто где-то вычитал что идёт ссылка именно на подвыражение регулярного выражения. Пример приводился именно такой.