2010-05-08 39 views
2

我正在嘗試正確提取方法定義,這些定義由使用正則表達式的COM接口的comtypes生成。而且其中一些是空白的,這對我造成了更多的問題。我如何使用Python Regex來做到這一點?

基本上我有這樣的:

IXMLSerializerAlt._methods_ = [ 
    COMMETHOD([helpstring(u'Loads an object from an XML string.')], HRESULT, 'LoadFromString', 
       (['in'], BSTR, 'XML'), 
       (['in'], BSTR, 'TypeName'), 
       (['in'], BSTR, 'TypeNamespaceURI'), 
       (['retval', 'out'], POINTER(POINTER(IUnknown)), 'obj')), 
] 

class EnvironmentManager(CoClass): 
    u'Singleton object that manages different environments (collections of configuration information).' 
    _reg_clsid_ = GUID('{8A626D49-5F5E-47D9-9463-0B802E9C4167}') 
    _idlflags_ = [] 
    _typelib_path_ = typelib_path 
    _reg_typelib_ = ('{5E1F7BC3-67C5-4AEE-8EC6-C4B73AAC42ED}', 1, 0) 

INumberFormat._methods_ = [ 
] 

我想提取兩個IXMLSerializerAlt和INumberFormat方法定義,但是我不能想出一個合適的正則表達式。例如。對於IXMLSerializer我想提取這樣的:

IXMLSerializerAlt._methods_ = [ 
    COMMETHOD([helpstring(u'Loads an object from an XML string.')], HRESULT, 'LoadFromString', 
       (['in'], BSTR, 'XML'), 
       (['in'], BSTR, 'TypeName'), 
       (['in'], BSTR, 'TypeNamespaceURI'), 
       (['retval', 'out'], POINTER(POINTER(IUnknown)), 'obj')), 
] 

此正則表達式在我的腦海這應該工作:

^\w+\._methods_\s=\s\[$ 
(^.+$)* 
^]$ 

進出口檢查我的正則表達式的使用科多獸,但是我不能想出一個辦法,使這項工作。

+0

您正則表達式中包含美元在無效的地方,比如在它的第一行結束,所以它不能匹配。另一個問題是方括號嵌套在上面的語法中,所以使用單個正則表達式並不容易。 – fviktor 2010-05-08 23:29:54

+0

@fviktor:如果啓用多行匹配('m'或're.MULTILINE'標誌),則美元可以到達任何地方 - 美元在行尾匹配。至於嵌套的方括號,他選擇了一個不太完美的解決方案,它只需匹配一個線條上的一個方形支架即可。 – 2010-05-08 23:31:46

+0

我知道這不是你確切的問題,但是直接從'comtypes'提取這些信息而不解析接口定義會更容易嗎? – fviktor 2010-05-08 23:33:41

回答

2

您錯過了$^之間的換行符,並且可能沒有使用re.MULTILINE標誌,該標誌允許將這些標誌固定在行的開頭和結尾。以下(含re.MULTILINE編譯)會匹配:

\w+\._methods_\s=\s\[$(?:\n^.+$)*\n^\]$ 

但是,這裏有一個稍微simpliifed正則表達式,也將匹配您的例子:

>>> s = '''...\nIXMLSerializerAlt._methods_ = [\n COMMETHOD([helpstring(u'Loads an object from an XML string.')], HRESULT, 'LoadFromString',\n    (['in'], BSTR, 'XML'),\n    (['in'], BSTR, 'TypeName'),\n    (['in'], BSTR, 'TypeNamespaceURI'),\n    (['retval', 'out'], POINTER(POINTER(IUnknown)), 'obj')),\n]\n...''' 
>>> import re 
>>> re.findall(r'^\w+\._methods_\s=\s\[$.*?^\]$', s, re.DOTALL | re.MULTILINE) 
["IXMLSerializerAlt._methods_ = [\n COMMETHOD([helpstring(u'Loads an object from an XML string.')], HRESULT, 'LoadFromString',\n    (['in'], BSTR, 'XML'),\n    (['in'], BSTR, 'TypeName'),\n    (['in'], BSTR, 'TypeNamespaceURI'),\n    (['retval', 'out'], POINTER(POINTER(IUnknown)), 'obj')),\n]"] 
+0

這樣做:)謝謝。 – UberJumper 2010-05-08 23:30:02

0
import re 

interface_definitions = ''' 
IXMLSerializerAlt._methods_ = [ 
    COMMETHOD([helpstring(u'Loads an object from an XML string.')], HRESULT, 'LoadFromString', 
       (['in'], BSTR, 'XML'), 
       (['in'], BSTR, 'TypeName'), 
       (['in'], BSTR, 'TypeNamespaceURI'), 
       (['retval', 'out'], POINTER(POINTER(IUnknown)), 'obj')), 
] 

class EnvironmentManager(CoClass): 
    u'Singleton object that manages different environments (collections of configuration information).' 
    _reg_clsid_ = GUID('{8A626D49-5F5E-47D9-9463-0B802E9C4167}') 
    _idlflags_ = [] 
    _typelib_path_ = typelib_path 
    _reg_typelib_ = ('{5E1F7BC3-67C5-4AEE-8EC6-C4B73AAC42ED}', 1, 0) 

INumberFormat._methods_ = [ 
] 
''' 

RX_METHODS = re.compile(
    r'(\w+)\._methods_\s=\s\[(' 
    r'.*?' 
    r'(?:\[.*?\].*?)*' 
    r')\]', 
    re.DOTALL) 

for match in RX_METHODS.finditer(interface_definitions): 
    print match.groups() 
相關問題