Python регулярное выражение вырезать строку шаблона

1

У меня есть файл с такой информацией:

 id                      : 1234567890
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 9876543210
 6)address               : street number
 data                    : [42|63] [42|62]

 id                      : 14785236984
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 987555555555
 6)address               : street number
 data                    : [44|67] [21|1024]          
 id                      : 987456321
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 98744444444
 6)address               : street number
 data                    : [26|1089] [21|1524]

Я хочу разделить эту информацию по регулярному выражению, потому что не все блоки разделены с новой строкой ('\n'), поэтому мне будет трудно сделать это с помощью split, который я пытался сделать с регулярным выражением:

^[\s]id[\w\W\s\S\t]+(\[\d{1,}\|\d{1,}\]{,2})$

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

  1. группа первая

     id                      : 1234567890
     1)client_name           : Abcd
     2)family_name           : Efgh
     5)phon_number           : 9876543210
     6)address               : street number
     data                    : [42|63] [42|62]
    
  2. группа вторая

     id                      : 14785236984
     1)client_name           : Abcd
     2)family_name           : Efgh
     5)phon_number           : 987555555555
     6)address               : street number
     data                    : [44|67] [21|1024]
    
  3. группа три

    id                      : 987456321
    1)client_name           : Abcd
    2)family_name           : Efgh
    5)phon_number           : 98744444444
    6)address               : street number
    data                    : [26|1089] [21|1524]
    
Теги:
regex-group

4 ответа

0
Лучший ответ

Этот способ кажется простым и легким для чтения:

l = re.split(r'\n+(?=\s*id\b)', s.strip(), flags=re.M)
print l

Разделение по символу newline/s начинается с id. Также вы берете исходную строку и снимаете ее.

Демо: https://ideone.com/No5vva

1

Это регулярное выражение будет разделять входной текст на группы, начинающиеся с id (вы можете опустить .strip() если хотите сохранить пробелы). Объяснение этого регулярного выражения здесь.

data="""
 id                      : 1234567890
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 9876543210
 6)address               : street number
 data                    : [42|63] [42|62]

 id                      : 14785236984
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 987555555555
 6)address               : street number
 data                    : [44|67] [21|1024]
 id                      : 987456321
 1)client_name           : Abcd
 2)family_name           : Efgh
 5)phon_number           : 98744444444
 6)address               : street number
 data                    : [26|1089] [21|1524]
"""

import re
from pprint import pprint

pprint([i.strip() for i in re.findall(r'id\s*:.*?(?=id|\Z)', data, flags=re.DOTALL)], width=120)

Результатом будет список из 3 строк (я установил новую строку между ними, чтобы увидеть это ясно):

['id                      : 1234567890\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 9876543210\n'
 ' 6)address               : street number\n'
 ' data                    : [42|63] [42|62]',

 'id                      : 14785236984\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 987555555555\n'
 ' 6)address               : street number\n'
 ' data                    : [44|67] [21|1024]',

 'id                      : 987456321\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 98744444444\n'
 ' 6)address               : street number\n'
 ' data                    : [26|1089] [21|1524]']
0

Вы можете использовать re.split(r'\s(?=id)', s) чтобы разделить всю строку на разделы, затем разделить каждую строку в разделах и затем разбить каждую строку на основе : для преобразования в dict

>>> s="""id                      : 1234567890
...  1)client_name           : Abcd
...  2)family_name           : Efgh
...  5)phon_number           : 9876543210
...  6)address               : street number
...  data                    : [42|63] [42|62]
... 
...  id                      : 14785236984
...  1)client_name           : Abcd
...  2)family_name           : Efgh
...  5)phon_number           : 987555555555
...  6)address               : street number
...  data                    : [44|67] [21|1024]          
...  id                      : 987456321
...  1)client_name           : Abcd
...  2)family_name           : Efgh
...  5)phon_number           : 98744444444
...  6)address               : street number
...  data                    : [26|1089] [21|1524]"""
>>> 
>>> import re
>>> sections = re.split(r'\s(?=id)', s)
>>> ld = [dict(map(str.strip, line.split(':')) for line in section.splitlines() if line) for section in sections]
>>> 
>>> pprint (sections)
['id                      : 1234567890\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 9876543210\n'
 ' 6)address               : street number\n'
 ' data                    : [42|63] [42|62]\n'
 '\n',
 'id                      : 14785236984\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 987555555555\n'
 ' 6)address               : street number\n'
 ' data                    : [44|67] [21|1024]          \n',
 'id                      : 987456321\n'
 ' 1)client_name           : Abcd\n'
 ' 2)family_name           : Efgh\n'
 ' 5)phon_number           : 98744444444\n'
 ' 6)address               : street number\n'
 ' data                    : [26|1089] [21|1524]']
>>> 
>>> pprint (ld)
[{'1)client_name': 'Abcd',
  '2)family_name': 'Efgh',
  '5)phon_number': '9876543210',
  '6)address': 'street number',
  'data': '[42|63] [42|62]',
  'id': '1234567890'},
 {'1)client_name': 'Abcd',
  '2)family_name': 'Efgh',
  '5)phon_number': '987555555555',
  '6)address': 'street number',
  'data': '[44|67] [21|1024]',
  'id': '14785236984'},
 {'1)client_name': 'Abcd',
  '2)family_name': 'Efgh',
  '5)phon_number': '98744444444',
  '6)address': 'street number',
  'data': '[26|1089] [21|1524]',
  'id': '987456321'}]
>>> 
0

Вероятно, было бы легче split по пробелам, с учетом id за которым следует пробел:

re.compile("\s+(?=id\s{22}:)").split(s)

https://ideone.com/FSgVrN

Ещё вопросы

Сообщество Overcoder
Наверх
Меню