Regex для поиска между двумя последовательными вхождениями строки, второе, которое может быть необязательным - PullRequest
0 голосов
/ 11 сентября 2018

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

Heading 1
   SubheadingA: SomethingX
   SubheadingB: SomethingY
   SubheadingC: SomethingZ

и я хочу найти значение рядом с SubheadingB под заголовком 1, то есть SomethingY.

Это может выглядеть следующим образом, и регулярное выражение не будет ничего соответствовать:

Heading 1
   SubheadingA: SomethingX
   SubheadingC: SomethingZ

или это может выглядеть так и возвращать SomethingY:

Heading 1
   SubheadingA: SomethingX
   SubheadingB: SomethingY
   SubheadingC: SomethingZ

Heading 2
   SubheadingA: SomethingU
   SubheadingB: SomethingV
   SubheadingC: SomethingW

Я думал, что у меня есть решение с этим регулярным выражением:

Heading\s+(1).*?SubheadingB:\s+(.*?)\n.*?(Heading)?

Однако это все равно возвращает совпадение в следующей ситуации:

Heading 1
   SubheadingA: SomethingX
   SubheadingC: SomethingZ

Heading 2
   SubheadingA: SomethingU
   SubheadingB: SomethingV
   SubheadingC: SomethingW

Heading 3
   SubheadingA: SomethingR
   SubheadingB: SomethingS
   SubheadingC: SomethingT

SomethingV возвращается, так как «Заголовок 1» был найден, за которым следует «Подзаголовок B» в «Заголовке 2» и «Заголовок 3», что не является тем, что я хочу.

Это может быть даже расширено до гораздо более длинного примера, где мне просто нужно искать между "Заголовком 1" и самым последующим вхождением "Заголовка" для этого конкретного Подзаголовка и его значения:

Heading -1
   SubheadingB: SomethingBB
   SubheadingC: SomethingCC

Heading 0
   SubheadingA: SomethingDD
   SubheadingB: SomethingEE
   SubheadingC: SomethingFF

Heading 1
   SubheadingA: SomethingX
   SubheadingB: SomethingY
   SubheadingC: SomethingZ

Heading 2
   SubheadingA: SomethingGG
   SubheadingB: SomethingHH

Heading 3
   SubheadingA: SomethingJJ
   SubheadingB: SomethingKK
   SubheadingC: SomethingLL

Я бы хотел, чтобы он возвращал SomethingY или вообще ничего, если "Заголовок 1 -> ПодзаголовокB -> Какое бы значение" не было найдено.

Что я мог бы использовать, чтобы указать вхождение заголовка после заголовка 1, которое может произойти или не произойти? Спасибо!

РЕДАКТИРОВАТЬ: Забыли жадные совпадения между новой строкой и опциональным заголовком. Я использую символ новой строки, потому что в SomethingY может быть пробел, поэтому регулярное выражение может захватывать из:

SubheadingB: Something Y

и должен вернуть «Something Y».

1 Ответ

0 голосов
/ 11 сентября 2018

Вы не хотите пропускать другой Heading.Для этого вы можете установить линии между, чтобы не начинать с использованием отрицательного lookahead .Пример в виде строки Java с флагом MULTILINE и без DOTALL.

"^Heading +(1).*(?:\\r?\\n(?! *Heading).*)*?\\r?\\n.*?SubheadingB: *(.*)"

См. Эти демонстрационные примеры на regex101: [1] [2] [3] (не Java)

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