Остановитесь в первый раз в Regex - PullRequest
3 голосов
/ 18 октября 2019

У меня есть текст, содержащий информацию только об одном человеке, но много информации о разных домашних животных. Я ищу способ выбрать только данные о человеке с помощью Regex.

Вот что я пробовал

ТЕКСТ:

# Person
---
Name: Nick King 
Age: 18
Speech: "Hello!! How are you? Me & you are different. I'm the #1"

# Pet = Dog
---
Name: Bill

# Pet = Cat
---
Name: Zacky

REGEX:

#\s*Person(\n|.)+(?=#\s*Pet)

Regex всегда идет и захватывает до последнего питомца из-за тега anychar (.) У меня естьused.

Как я могу остановиться на первом питомце?

Предполагая, что "Dog" не всегда будет первым питомцем в списке.

Ответы [ 2 ]

2 голосов
/ 18 октября 2019

Вы используете (\n|.)+, который слишком много соответствует, но также очень неэффективен, поскольку он чередуется между любым символом или новой строкой.

Вы можете сопоставить # Person и повторить сопоставление всех строк, которые не начинаютсяс # Pet

#\s*Person(?:\r?\n(?!#\s*Pet\b).*)*
  • #\s*Person Match # Person
  • (?: Группа без захвата
    • \r?\n Соответствие новой строки
    • (?!#\s*Pet\b).* Соответствует всей строке, когда не начинается с # Pet
  • )* Закройте группу и повторите 0+ раз

Regex demo

2 голосов
/ 18 октября 2019

Regex, возможно, не лучшее решение для такого рода проблем - есть интерпретаторы YAML, которые вы могли бы использовать.

Если вы решили использовать регулярные выражения, есть простое решение: быть нечестным.

Locally Ungreedy

В вашем исходном регулярном выражении вы имели:

#\s*Person(\n|.)+(?=#\s*Pet)

В этом (\n|.)+ соответствует столько символов, сколько возможно допроведение взгляда Pet.

Если вы введете ? после +, чтобы эта группа читала (\n|.)+, вы получите как можно меньше символов перед проведениемlookahead.

#\s*Person(\n|.)+?(?=#\s*Pet)

Regex101 описывает +? следующим образом:

+? Квантор - Соответствует между один и неограниченное количество раз , как можно меньше раз, расширяясь по мере необходимости (ленивый)

Global Ungreedy

Помимо работы с локальным переключателем ungreedy , вы можете установить глобальноквантификаторы должны быть ungreedy при использовании флага U .

Обратите внимание, что это полностью меняет жадность, поэтому, если вы установите флаг U , а также используете +?, вы снова будете сопоставлять столько раз, сколько возможно . Используйте одно решение или другое.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...