Регулярное выражение для поиска совпадений между пользователями вместо поиска по всем данным

#python #regex #data-analysis

Вопрос:

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

 00~XXXXXXXXXXXXXX24~
01~John~Doe~Bank~Name~XXXXXXX00~ABCD0123456~
And then some other data which is not required
00~XXXXXXXXXXXXXX23~
01~Jane~Doe~Bank~Name~XXXXXXX00~ABCD0123456~
And then some other data which is not required
 

Итак, из этих данных я хочу извлечь 16-значный код после 00~, 9-значный код после названия банка, а затем код IFSC для каждого пользователя.

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

 demat = re.findall("00~d{16}~", content)
micr = re.findall("~d{9}~", content)
ifsc = re.findall("[A-Z]{4}0[A-Z0-9]{6}", content)
 

Однако, используя это, python сопоставляет все регулярные выражения независимо (demat, micr и ifsc независимо) и возвращает все это в списках разной длины (возможно, из-за отсутствия данных), из-за чего я не могу хранить полную информацию пользователя.

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

Любая помощь будет очень признательна!

Комментарии:

1. Пожалуйста, четко сформулируйте формат вывода, к которому вы стремитесь.

Ответ №1:

Вы можете захватить все части в одном регулярном выражении, используя re.finditer :

 rx = r'^00~(?P<demat>d{16})~r?nd (?:~[^~]*){4}~(?P<micr>[^~]*)~(?P<ifsc>[^~]*)~'
with open(filepath, 'r') as f:
    for m in re.finditer(rx, f.read(), re.M):
        print(m.groupdict())
 

Смотрите демонстрацию регулярных выражений. Обратите внимание, что micr ifsc данные и могут быть пустыми, так как [^~]* шаблон может соответствовать пустой строке.

Подробные сведения:

  • ^ — начало строки
  • 00~ 00~ струна
  • (?P<demat>d{16}) — 16 цифр, записанных в demat группе
  • ~r?n ~ и окончание строки CRLF или LF
  • d — одна или несколько цифр
  • (?:~[^~]*){4} — четыре вхождения ~ и ноль или более символов, отличных от ~
  • ~ — а ~ чар
  • (?P<micr>[^~]*) — Группа «micr»: любые нулевые или более символов, кроме ~
  • ~ — а ~ чар
  • (?P<ifsc>[^~]*) — Группа «ifsc»: любые нулевые или более символов, кроме ~
  • ~ — а ~ чар

Смотрите демонстрационную версию Python:

 import re
file = "00~1234567890123424~n01~John~Doe~Bank~Name~123456700~ABCD0123456~nAnd then some other data which is not requiredn00~1234567890123423~n01~Jane~Doe~Bank~Name~123456700~ABCD0123456~nAnd then some other data which is not required"
rx = r'^00~(?P<demat>d{16})~r?nd (?:~[^~]*){4}~(?P<micr>[^~]*)~(?P<ifsc>[^~]*)~'
for m in re.finditer(rx, file, re.M):
    print(m.groupdict())
 

Выход:

 {'demat': '1234567890123424', 'micr': '123456700', 'ifsc': 'ABCD0123456'}
{'demat': '1234567890123423', 'micr': '123456700', 'ifsc': 'ABCD0123456'}