Захватить строки в кавычках - PullRequest
0 голосов
/ 23 октября 2019

У меня есть 3 строки в этом формате

Bank: {"955974044748481":["BANK_A"]}
{"reason": "Bank: {"455049295219902":["BANK_B"]}"}
{"reason": "Bank: {\\"1876212592475597\\":[\\"BANK_C\\"]}"}

Мне нужно извлечь bank_id и bank_name из этих строк, используя одно регулярное выражение в операторе presto SQL.

Я пробовал это регулярное выражение, но он захватывает только первые два, а не последний, который имеет escape-символы. https://regex101.com/r/ejW68x/1

Bank: {"(.*)":\["(.*)"\]}

Как правильно захватить все 3 варианта?

1 Ответ

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

Примерно так:

Bank:.*{(?:\\\\)?"([^{"]*?)(?:\\\\)?":\[(?:\\\\)?"(.*?)(?:\\\\)?"\]}

Демо .

Или чтобы убедиться, что \\ сопоставляются только парами:

Bank:.*{((?:\\\\)?)"([^{"]*?)\1":\[((?:\\\\)?)"(.*?)\3"\]}

Демо .

Обратите внимание, что во втором случае ваши снимки будут в группах №2 и №4.


Обновление:

Ваши новые тестовые строки все равно будут соответствовать указанным выше шаблонам. Вы можете просто заменить Bank:.* на Bank:[ ], если хотите. Demo1 - Demo2 .

Объяснение: (изменения в вашем шаблоне)

  • Добавлено (?:\\\\)? -> Необязательная группа без захвата для соответствия двум символам обратной косой черты.

  • Заменена ваша первая группа захвата (.*)с ([^{"]*?), чтобы избежать совпадения с двойными кавычками и { символами (это особенно необходимо для ваших первых тестовых строк). Кроме того, преобразовал его из жадного в ленивый (добавив ?), чтобы избежать захвата экранирующих символов (\\), если он присутствует.

  • Сделал вторую группу захвата также ленивой (.*?) по той же причине.

  • Во втором шаблоне (?:\\\\)? был добавлен в группу захвата, чтобы можно было использовать обратную ссылку (т. Е. \1 и \3). Цель состоит в том, чтобы совпадать только в том случае, если экранированы оба символа двойной кавычки (перед \\).

...