RegEx для обеспечения и поиска последнего совпадения - PullRequest
1 голос
/ 17 мая 2019

Я пытаюсь извлечь часть имени из строки. У меня почти это есть, но что-то не так, когда я использую позитивный взгляд.

Вот мое регулярное выражение: (?=s\s(.*?)$)

Я отметил все результаты, которые хочу, с помощью полужирный текст.

Trittbergets Ronja

Минитигер Саманта Младший

Бьорнторпец Чита

Sors Kelly's Majsskalle

Проблема в том, что возвращается Kelly's Majsskalle, когда нужно выбрать только Majsskalle.

Вот ссылка на regex101 для отладки: https://regex101.com/r/PZWxr7/1

Как я могу получить упущение, чтобы не обращать внимания на первый матч?

Ответы [ 3 ]

3 голосов
/ 17 мая 2019

Не нужно смотреть вперед. Просто попробуйте это:

.*s\s(.*?)$
3 голосов
/ 17 мая 2019

Вам нужно включить механизм регулярных выражений, чтобы найти последнее совпадение, используя точку-звездочку:

^.*s\s(.*)$

A .* немедленно потребляет все, вплоть до перехода на новую строку, а затем откатывает движок, чтобы соответствовать следующему шаблону.

См. живую демонстрацию здесь

или используйте закаленную точку:

s(?= ((?:(?!s ).)+)$)
      ^^^^^^^^^^
  Match a byte only if we are not pointing at a `s[ ]`

См. живую демонстрацию здесь

Примечание : первое - лучшее решение.

2 голосов
/ 17 мая 2019

Предварительный просмотр должен использоваться для определения начала или конца захвата. Чтобы начать захват после первого захвата, вам нужно использовать просмотр сзади - это гарантирует, что текст ДО того, как захват окажется тем шаблоном поиска.

Обновите свой шаблон на regex101 до этого, и вы увидите разницу:

(?<=s\s).*?$

Редактировать - плохо, я не заметил эту последнюю строку.

Вы также можете включить отрицательный прогноз, чтобы убедиться, что в следующем совпадении нет другого слова, заканчивающегося s:

(?<=s\s)(?!.+?s\s).*?$

Это решает проблему с последней строкой.

...