Соответствие регулярного выражения многострочным блокам в python - PullRequest
0 голосов
/ 23 марта 2020

У меня возникли некоторые проблемы с использованием регулярного выражения Python при сопоставлении многострочного текста. Файл

(do c .txt):

<sec name="M_20_K40745170" sound_freq="mhr17:7907527-7907589" tension="SGCGSCGSCGSCGSC" s_c="0">
<feature number="5748">
<tfgt v="0.1466469683747654" y="0.0" units="sec"/>
</feature>
<mwan sound_freq="mhr17:7907527-7907589" first_name="g7tty" description="xyz">
<xyz abc="trt" id="abc"/>
<per fre="accessions" value="abc"/>
<per fre="xyz" value="abc"/>
<per fre="yy" value="abc"/>
<per fre="psc" value="abc"/>
<per fre="ttt" value="1"/>
<per fre="xyz" value="abc"/>
<per fre="Volum_5Kb" value="89.00"/>
<per fre="Volum_40Kb" value="00.00"/>
<per fre="Volum_70Kb" value="77.00"/>
</mwan>
</com>

Я хочу извлечь или сопоставить:

<sec name="M_20_K40745170" sound_freq="mhr17:7907527-7907589" tension="SGCGSCGSCGSCGSC" s_c="0">
pattern = re.compile(r'<sec name="(\D_\d\d_\w+)"\s+sound_freq="(\D\D\D\d+:\d+-\d+)"')

<per fre="Volum_5Kb" value="89.00"/>
<per fre="Volum_40Kb" value="00.00"/>
<per fre="Volum_70Kb" value="77.00"/>
pattern = re.compile(r'<sec name="(\D_\d\d_\w+)"\s+sound_freq="(\D\D\D\d+:\d+-\d+)"')

Это сработало для меня по двум различным схемам. Код Я пытаюсь получить два шаблона одновременно:

    import re 
    infile = open("/home/doc.txt")
    np_array_values = []
    pattern = re.compile(r'<sec name="(\D_\d\d_\w+)"\s+sound_freq="(\D\D\D\d+:\d+-\d+).*<per fre="(Volum_.*)"\s+value="(\d+.\d+)"/>"',re.DOTALL|re.MULTILINE)

    fn_list = infile.readlines() 
    for line in fn_list:
        search_obj = re.search(pattern, line)  
        print(search_obj)
        if search_obj:
            matching_group = search_obj.groups()
            print(matching_group)

Как мне заставить это работать?

1 Ответ

0 голосов
/ 24 марта 2020

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

def parse_doc(filename):
    with open(filename) as f:
        pattern1 = re.compile(r'<sec name="(\D_\d\d_\w+)"\s+sound_freq="(\D\D\D\d+:\d+-\d+)"')
        pattern2 = re.compile(r'<per fre="(Volum_+\d+Kb)"+\svalue="(\d+.+)"')

        doc = []
        for i in f.readlines():
            p1 = re.match(pattern1, i)
            p2 = re.match(pattern2, i)
            line = {}
            if p1:
                line.update({'sec': p1.group(1), 'sound_freq': p1.group(2)})
            if p2:
                line.update({p2.group(1): p2.group(2)})
            if len(line)>0:
                doc.append(line)

        return doc

print(parse_doc('doc.txt'))

Вывод

[{'sec': 'M_20_K40745170', 'sound_freq': 'mhr17:7907527-7907589'}, {'Volum_5Kb': '89.00'}, {'Volum_40Kb': '00.00'}, {'Volum_70Kb': '77.00'}]

Если вы хотите получить все значения, которые вы можно получить, используя следующее:

def parse_doc_all(filename):
    with open(filename) as f:
        pattern1 = re.compile(r'(.|\w+)="([^\s]+)"')
        doc = {}
        for i in f.readlines():
            doc.update({p[0]: p[1] for p in re.findall(pattern1, i)})

        return doc

print(parse_doc_all('doc.txt'))

Что даст вам

{'name': 'M_20_K40745170', 'sound_freq': 'mhr17:7907527-7907589', 'tension': 'SGCGSCGSCGSCGSC', 's_c': '0', 'number': '5748', 'v': '0.1466469683747654', 'y': '0.0', 'units': 'sec', 'first_name': 'g7tty', 'description': 'xyz', 'abc': 'trt', 'id': 'abc', 'fre': 'Volum_70Kb', 'value': '77.00'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...