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

У меня есть эти тестовые данные:

  1. Часть выполнена #400 - Azerjahan Husbai
  2. Акции к № 343 - Исполнители поместья № 18 - Хомахо Джурей
  3. Доли в качестве управляющего имуществом от № 187 - Шоне Джумая до № 448 - Сокса Хусмай.
  4. Доля в качестве управляющего имуществом от № 187 - Шон Джумаджа до № 445 - Хоро Те Фука.

У меня есть это регулярное выражение

^.*#(?<legacyId>\d*).*$

Группа захвата здесь всегда захватывает последнее вхождение #\d* Таким образом, текущий набор результатов захваченной группы с моим текущим регулярным выражением

  1. 400
  2. 18
  3. 448
  4. 445

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

  1. 400
  2. 343
  3. 448
  4. 445

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

Я подозреваю, что мне нужно использовать комбинацию положительного и отрицательного взгляда вперед?


person ambidexterous    schedule 19.04.2012    source источник


Ответы (1)


Вы не указали, какой язык программирования или библиотеку регулярных выражений вы используете. Это критическая информация. Без него я могу только догадываться, какие функции вам доступны.

Единственной существенной подсказкой, которую вы дали, было использование именованного захвата. Поскольку вы использовали синтаксис (?<name>), а не (?P<name>), это сужает ваш вариант регулярного выражения, вероятно, до одного из следующих:

  • .СЕТЬ
  • Перл 5.10+
  • ПКРЕ 7+
  • Ява 7+
  • Онигурума 1.8.4+
  • Ruby 1.9+ (который по умолчанию использует Oniguruma)
  • Boost.Regex (не уверен, какая версия начала поддерживать это)
  • JavaScript с XRegExp 0.5+
  • Продукты JGsoft, такие как RegexBuddy

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

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

^.*#(?<!estate of #)(?<legacyId>\d+)

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

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

person slevithan    schedule 29.05.2012