Перечислите все совпадения с одним или несколькими регулярными выражениями - PullRequest
0 голосов
/ 16 февраля 2020

Я пытаюсь токенизировать имена химических веществ организации, то есть разделить «гексан» на ['hex', 'an', 'e'], его составные части.

В основе этой проблемы лежит: как мне перечислить ~ все ~ совпадения с "одним или несколькими" регулярными выражениями, а не только с последним совпадением с этим регулярным выражением?

Я тестирую используя следующий код:

    print("Regex:", reg)
    print("Findall:", re.findall(reg, name))
    print("Finditer", [item.groups() for item in list(re.finditer(reg, name))])
    print("Search:", re.search(reg, name).groups())
    print("Split", re.split(reg, name))
    print("Match", re.match(reg, name).groups())

Во всех моих тестах name = "hexane". Это должно разобраться в ['hex', 'an', 'e']. Мои попытки регулярных выражений следуют шаблону "\ A ({здесь добавлено много групп, разделенных столбцами}) \ Z", где множество групп являются подмножеством префиксов и суффиксов, доступных для c химических веществ.

При использовании регулярного выражения без скобок в каждом разделе моего регулярного выражения я получаю следующий вывод:

Regex: \A((-|nonadeca|heptadeca|tetradec|imine|hept|heptadec|benzene|cyclo|oate|tetradeca|hex|yn|octa|phenyl|arsine|yl|dodec|e|eth|meth|pentadec|nona|phosphino|octadec|di|formyl|arsino|oct|oxo|tridec|penta|pent|dodeca|hydroxy|hexadec|hexa|ol|an|oyl|ether|non|trideca|prop|undec|hepta|pentadeca|nonadec|amine|tri|but|carbonyl|deca|en|amino|undeca|hexadeca|thiol|oxy|tetra|dec|carboxy|chloro|mercapto|iodo|fluoro|octadeca|imino|bromo|al|phosphine|carboxylicacid|amide|one|amido|oicacid)+)\Z
Findall: [('hexane', 'e')]
Finditer [('hexane', 'e')]
Search: ('hexane', 'e')
Split ['', 'hexane', 'e', '']
Match ('hexane', 'e')

Это показывает, что регулярное выражение должно правильно найти ['hex', 'an', 'e '], так как никакая другая комбинация частей не обеспечит полное совпадение \ A-STUFF_IN_HERE- \ Z. Тем не менее, ни один из результатов не дает молекулы, расщепленной на составные части для моего использования.

Размещение скобок вокруг каждой части дает следующий результат:

Regex: \A(-|(tetradec)|(thiol)|(phenyl)|(arsino)|(carbonyl)|(one)|(e)|(fluoro)|(ol)|(ether)|(eth)|(trideca)|(hex)|(iodo)|(nonadeca)|(non)|(pent)|(al)|(octa)|(octadec)|(di)|(undeca)|(arsine)|(tri)|(cyclo)|(prop)|(nona)|(dodec)|(phosphine)|(yn)|(but)|(an)|(heptadeca)|(carboxy)|(imine)|(hept)|(octadeca)|(amide)|(imino)|(deca)|(dodeca)|(oct)|(hydroxy)|(bromo)|(undec)|(pentadeca)|(tetra)|(hexadec)|(benzene)|(phosphino)|(hexa)|(tridec)|(mercapto)|(dec)|(oyl)|(oxy)|(meth)|(penta)|(amido)|(oicacid)|(amine)|(yl)|(nonadec)|(tetradeca)|(hexadeca)|(carboxylicacid)|(amino)|(chloro)|(pentadec)|(en)|(hepta)|(heptadec)|(formyl)|(oate)|(oxo))+\Z
Findall: [('e', '', '', '', '', '', '', 'e', '', '', '', '', '', 'hex', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', 'an', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '')]
Finditer [('e', None, None, None, None, None, None, 'e', None, None, None, None, None, 'hex', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 'an', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None)]
Search: ('e', None, None, None, None, None, None, 'e', None, None, None, None, None, 'hex', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 'an', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None)
Split ['', 'e', None, None, None, None, None, None, 'e', None, None, None, None, None, 'hex', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 'an', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, '']
Match ('e', None, None, None, None, None, None, 'e', None, None, None, None, None, 'hex', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, 'an', None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None)

Это снова показывает, что [' hex ',' an ',' e '] части успешно разбираются, но это не дает мне эти части в простом списке.

Примечание: Есть такие двусмысленности, как между "hex" и префиксы "hexa", которые делают простой re.split или re.findall слева направо без использования спецификатора \ A \ Z. Любой из приоритетов go будет "hex" во всех случаях, и в этом случае "hexapentyldecane" будет анализироваться как ["hex", ?????], прерванный конечным "a", или приоритет будет go в "гекса", так что "гексан" будет разбираться как ["гекса", ???], разбитый конечным "n".

1 Ответ

1 голос
/ 16 февраля 2020

Когда вы заранее не знаете, сколько будет групп совпадений, одно регулярное выражение не сможет собрать их всех в удобной структуре. Но вы можете l oop или просто разделить.

import re

string = 'hexane'
while True:
    oldstring = string
    string = re.sub(r'\A(-|nonadeca|heptadeca|tetradec|imine|hept|heptadec|benzene|cyclo|oate|tetradeca|hex|yn|octa|phenyl|arsine|yl|dodec|e|eth|meth|pentadec|nona|phosphino|octadec|di|formyl|arsino|oct|oxo|tridec|penta|pent|dodeca|hydroxy|hexadec|hexa|ol|an|oyl|ether|non|trideca|prop|undec|hepta|pentadeca|nonadec|amine|tri|but|carbonyl|deca|en|amino|undeca|hexadeca|thiol|oxy|tetra|dec|carboxy|chloro|mercapto|iodo|fluoro|octadeca|imino|bromo|al|phosphine|carboxylicacid|amide|one|amido|oicacid)', '', string)
    if not string:
        print(oldstring)
        break
    print(oldstring[0:-len(string)])

Выше не очень элегантно, но, по крайней мере, вы должны начать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...