Почему «Год 2010» = ~ / ([0-4] *) / приводит к пустой строке в $ 1? - PullRequest
10 голосов
/ 21 октября 2010

Если я бегу

"Year 2010" =~ /([0-4]*)/;
print $1;

Я получаю пустую строку. Но

"Year 2010" =~ /([0-4]+)/;
print $1;

выходы "2010". Почему?

Ответы [ 7 ]

19 голосов
/ 21 октября 2010

Вы получаете пустое совпадение прямо в начале строки «Год 2010» для первой формы, потому что * будет сразу совпадать с 0 цифрами. Форме + придется подождать, пока она не увидит хотя бы одну цифру, прежде чем она совпадет.

Предположительно, если вы сможете пройти все совпадения первой формы, вы в конечном итоге найдете 2010 ... но, вероятно, только после того, как он найдет другое пустое совпадение до 'e', ​​а затем до «а» и т. д.

6 голосов
/ 21 октября 2010

Первое регулярное выражение успешно соответствует нулевым разрядам в начале строки, что приводит к захвату пустой строки.

Второму регулярному выражению не удается найти совпадение в начале строки, но оно соответствуеткогда он достигнет 2010 года.

5 голосов
/ 21 октября 2010

вы также можете использовать YAPE :: Regex :: Explain для объяснения регулярного выражения типа

use YAPE::Regex::Explain;

print YAPE::Regex::Explain->new('([0-4]*)')->explain();
print YAPE::Regex::Explain->new('([0-4]+)')->explain();

выход:

The regular expression:
(?-imsx:([0-4]*))
matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    [0-4]*                   any character of: '0' to '4' (0 or more
                             times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------

The regular expression:
(?-imsx:([0-4]+))
matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    [0-4]+                   any character of: '0' to '4' (1 or more
                             times (matching the most amount
                             possible))
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
)                        end of grouping
----------------------------------------------------------------------
5 голосов
/ 21 октября 2010

Первая соответствует строке нулевой длины в начале (до Y) и возвращает ее. Вторая ищет одну или несколько цифр и ждет, пока не найдет 2010.

1 голос
/ 22 октября 2010

У нас есть вопрос для подвоха в Learning Perl . Любое регулярное выражение, которое может соответствовать нулевым символам, не совпадающим в начале строки, будет соответствовать нулевым символам.

Движок регулярных выражений Perl соответствует самому длинному совпадению, а самая левая часть идет первой. Однако не все движки regex работают так. Если вам нужны все технические подробности, прочитайте Освоение регулярных выражений , в котором объясняется, как работают механизмы регулярных выражений, и находите совпадения.

1 голос
/ 21 октября 2010

Символ звезды пытается в основном соответствовать 0 или более символам в данном наборе (теоретически набор {x, y} * состоит из пустой строки и всех возможных конечных последовательностей, состоящих из x и y), и, следовательно, он будетсоответствует точно нулевым символам (пустая строка) в начале строки, нулевым символам после первого символа, нулевым символам после второго символа и т. д. Затем, наконец, он найдет 2 и будет соответствовать целому 2010 году.

Символ плюсасоответствует одному или нескольким символам из данного набора ({x, y} + состоит из всех возможных конечных последовательностей, состоящих из x и y, без пустой строки, в отличие от {x, y} *).Таким образом, первый встреченный совпадающий символ равен 2, затем следующий - проверяется 0, затем 1, затем еще один 0, а затем предложение заканчивается, поэтому найденная группа выглядит как '2010'.

Это стандартное поведение для обычноговыражения, определенные в теории формального языка.Я настоятельно рекомендую немного изучить теорию регулярных выражений, это не повредит, но может помочь:)

0 голосов
/ 22 октября 2010

Чтобы сделать первое совпадение RE, используйте якорь ' $ ':

"Year 2010" =~ /([0-4]*)$/;
 print $1;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...