Предположим, у меня есть следующий текст:
Name: John Doe\tAddress: Street 123 ABC\tCity: MyCity
У меня есть регулярное выражение (немного более сложное, но оно сводится к этому):
^(?:(?:(?:Name: (.+?))|(?:Address: (.+?))|(?:City: (.+?)))\t*)+$
, которое имеет три захватагруппы, которые могут захватывать значения имени, адреса и города (если они встречаются в тексте).Вот еще несколько примеров: https://regex101.com/r/37nemH/6. EDIT Порядок не фиксирован заранее, и также может случиться, что поля не разделены \t
символами.
Теперь все это работает хорошо, единственная небольшая проблема, с которой я сталкиваюсь, это когда одно поле встречается дважды в одном и том же тексте, как видно из последнего примера, который я поместил в regex101:
Name: John Doe\tAddress: Street 123 ABC\tCity: MyCity\tAddress: Other Address
Я бы хотел, чтобы вторая группа захвата совпадала с first address, то есть Street 123 ABC
, и, предпочтительно, чтобы второе вхождение совпадало внутри группы "City", т.е.
1: John Doe
2: Street 123 ABC
3: MyCity\tAddress: Other Address
Концептуально, я попытался сделать это с отрицательным взглядом, например, заменив (?:Address: (.+?))
на (?:(?<!.*Address: )Address: (.+?))
, то есть убедившись, что совпадение Address:
не было где-то в тексте другим тегом Address:
.Но отрицательный взгляд сзади не учитывает произвольную длину, поэтому это, очевидно, не сработает.
Можно ли это сделать с помощью регулярных выражений и как?