Perl регулярное выражение: почему не фиксируется дополнительная часть? - PullRequest
1 голос
/ 27 апреля 2020

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

Например, с этими двумя строками:

some text and number 18
some other text

Я хотел бы всегда захватывать «некоторые» и захватывать «18», если я вижу «число 18».

Использование /(some).*?(?:number (\d+))/ работает, конечно, с первой строкой, но не со второй:

$ echo "some text and number 18" | perl -nle '/(some).*?(?:number (\d+))/ && print join("\n", $1, $2)'
some
18
$ echo "some other text" | perl -nle '/(some).*?(?:number (\d+))/ && print join("\n", $1, $2)'
$

Но при использовании /(some).*?(?:number (\d+))?/ чтобы сделать последнюю часть необязательной, 1-е совпадение всегда фиксируется, но это не номер:

$ echo "some text and number 18" | perl -nle '/(some).*?(?:number (\d+))?/ && print join("\n", $1, $2)'
some

$ echo "some other text" | perl -nle '/(some).*?(?:number (\d+))?/ && print join("\n", $1, $2)'
some

$ 

Как я могу захватить необязательную часть?

1 Ответ

2 голосов
/ 27 апреля 2020

Вы можете использовать

/(some)(?:.*?number (\d+))?/

См. Демоверсию regex . Подробности:

  • (some) - группа 1: some
  • (?:.*?number (\d+))? - необязательная группа без захвата, которая будет пробоваться хотя бы один раз и будет пытаться соответствовать 1 или 0 вхождений
    • .*? - любые 0+ символов, кроме символов разрыва строки, как можно меньше
    • number - number строка
    • (\d+) - Группа 2: 1+ цифр

См. онлайн-демонстрацию :

perl -nle '/(some)(?:.*?number (\d+))?/ && print join("\n", $1, $2)' <<< "some text and number 18"
# some
# 18
perl -nle '/(some)(?:.*?number (\d+))?/ && print join("\n", $1, $2)' <<< "some other text"
# some
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...