在發表我的評論引用pyparsing的invRegex示例之後,我更仔細地看了一下您的輸入,看起來您可以將其解釋爲中綴表示法,其中','和' - '是二元運算符。 Pyparsing有一個名爲operatorPrecedence
的幫助器方法,它根據運算符的優先級解析表達式,並將其分組在括號中。 (這有更多一點的智慧把它比只使用nestedExpr
helper方法,它匹配嵌套組符號中的表達式。)因此,這裏是使用operatorPrecedence
解析器的工具入門版本:
data = """\
(A,B)-C-D
A-B-(C,D)
A-(B,C,D-(E,F,G,H,I))""".splitlines()
from pyparsing import alphas, oneOf, operatorPrecedence, opAssoc
node = oneOf(list(alphas))
graphExpr = operatorPrecedence(node,
[
('-', 2, opAssoc.LEFT),
(',', 2, opAssoc.LEFT),
])
for d in data:
print graphExpr.parseString(d).asList()
Pyparsing實際收益一個類型爲ParseResults的複雜結構,它支持對解析的記號作爲列表中的元素,字典中的項目或對象中的屬性進行訪問。通過調用asList
,我們只需獲取簡單列表形式的元素。
以上表明,我們看起來是在正確的軌道上的輸出:
[[['A', ',', 'B'], '-', 'C', '-', 'D']]
[['A', '-', 'B', '-', ['C', ',', 'D']]]
[['A', '-', ['B', ',', 'C', ',', ['D', '-', ['E', ',', 'F', ',', 'G', ',', 'H', ',', 'I']]]]]
Pyparsing也可以讓你的回調或parse actions
重視個人表現,在分析時被調用。例如,該解析動作確實分析時轉化爲整數:
def toInt(tokens):
return int(tokens[0])
integer = Word(nums).setParseAction(toInt)
當該值在ParseResults被返回,它已經被轉換爲整數。
也可以將類指定爲分析操作,並將ParseResults對象傳遞給該類的__init__
方法並返回結果對象。我們可以在operatorPrecedence中指定分析動作,方法是在每個運算符的描述符元組中添加分析動作作爲第4個元素。
這裏是二元運算符基類:
class BinOp(object):
def __init__(self, tokens):
self.tokens = tokens
def __str__(self):
return self.__class__.__name__ + str(self.tokens[0][::2])
__repr__ = __str__
從這個基類,我們可以推導出2子類,每一個運營商-
和,
:
class Path(BinOp):
pass
class Branch(BinOp):
pass
,並將它們添加到operatorPrecedence中的運算符定義元組:
node = oneOf(list(alphas))
graphExpr = operatorPrecedence(node,
[
('-', 2, opAssoc.LEFT, Path),
(',', 2, opAssoc.LEFT, Branch),
])
for d in data:
print graphExpr.parseString(d).asList()
這使我們對象的每個輸入串的嵌套結構:
[Path[Branch['A', 'B'], 'C', 'D']]
[Path['A', 'B', Branch['C', 'D']]]
[Path['A', Branch['B', 'C', Path['D', Branch['E', 'F', 'G', 'H', 'I']]]]]
的從這種結構中路徑的生成留給讀者作爲練習爲OP。 (pyparsing正則表達式逆變器使用一系列發生器執行此操作 - 希望一些簡單的遞歸就足夠了。)
謝謝您的建議。我會看看pyparsing。 – cytochrome
這與包含在pyparsing wiki(http://pyparsing.wikispaces.com)的Examples頁面中的正則表達式反轉示例非常相似。 – PaulMcG