2014-01-11 60 views
4

我想解析一個字符串使用pyparsing。使用下面的代碼沒有找到與pyparsing預期的字符串

import pyparsing as pyp 

aString = "C((H2)(C(H3))) C((H1)(Cl1)) C(((C(H3))3))" 

aSub = '(('+ pyp.Word('()'+pyp.srange('[A-Za-z0-9]'))+'))' 
substituent = aSub('sub') 

for t,s,e in substituent.scanString(aString): 
    print t.sub 

我得不到輸出。然而,在字符串aString = "C((H2)(C(H3))) C((H1)(Cl1)) C(((C(H3))3))"中存在多個出現((stuff)) - 具體((H2)(C(H3))),C((H1)(Cl1))C(((C(H3))3))

我對Word()的理解是,輸入(在單個輸入的情況下,就像我一樣)表示所有可能的字符組合,這些字符組合將成功返回匹配。

運行代碼

import pyparsing as pyp 

aString = "C((H2)(C(H3))) C((H1)(Cl1)) C(((C(H3))3))" 

aSub = '(' + pyp.Word(pyp.srange('[A-Za-z0-9]'))+')' 
substituent = aSub('sub') 

for t,s,e in substituent.scanString(aString): 
    print t.sub 

給出

['(', 'H2', ')'] 
['(', 'H3', ')'] 
['(', 'H1', ')'] 
['(', 'Cl1', ')'] 
['(', 'H3', ')'] 

輸出所有我已經改變了一個額外的外部組括號,以及字符串的括號內的選項,期望的字符串具有哪些。我不知道爲什麼第一個程序沒有給我什麼,而第二個字符串給了我(我的一部分)我想要的。

回答

2

問題是pyparsing工作從左到右(source)。因此右括號會擦除您在右邊搜索的內容。例如:

aSub = '(('+ pyp.Word('()'+pyp.srange('[A-Za-z0-9]')) 

回報

['((', 'H2)(C(H3)))'] 
['((', 'H1)(Cl1))'] 
['((', '(C(H3))3))'] 
+0

那麼,如果我不想擁有那個正確的圓括號,我該怎麼辦?如果我想要像'['(('','H2)(C(H3)','))']'?我只需添加一行代碼,將該字符串拆分爲兩部分,然後將其附加到列表中? – Dannnno

+0

@Dannnno添加一行代碼當然是一個合理的破解,但它可能不是最簡單/最快的。我現在不能提供更好的soln。 –

+1

如果您不希望包含右括號,則不應將其作爲Word表達式的一部分。問題在於Word不知道2個尾部的''是特殊的,所以它將它們包含在單詞組的其餘部分中。一些建議:檢查pyparsing'nestedExpr'。另外,我認爲'pyp.alphanums'比'pyp.srange('[A-Za-z0-9')'更容易閱讀。 – PaulMcG

1

正如保羅·麥圭爾的意見建議我發現,使用nestedExpr是我的情況的最佳選擇。使用下面的代碼

import pyparsing as pyp 

aString = "C((H2)(C(H3))) C((H1)(Cl1)) C((C(H3))3)" 
aList = aString.split() 

for i in range(len(aList)): 
    aList[i] = [pyp.nestedExpr().parseString(aList[i][1:]).asList()[0]] 

print aList 

我的

[[[['H2'], ['C', ['H3']]]], [[['H1'], ['Cl1']]], [[['C', ['H3']], '3']]] 

輸出這正是我想要的。