How can I do this using Python Regex?
I am trying to correctly extract method definitions that are generated by comtypes for Com interfaces using regex. Also, some of them are empty, which causes even more problems for me.
Basically I have this:
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_ = [
]
I want to extract both the definitions of the IXMLSerializerAlt and INumberFormat methods, but I cannot find the correct regex. For instance. for the IXMLSerializer, I want to extract this:
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' )),
]
This regex should work in my opinion:
^\w+\._methods_\s=\s\[$
(^.+$)*
^]$
I am validating my regex using kodos however I cannot figure out how to do it.
a source to share
You are missing newlines between $
and ^
and cannot use a flag re.MULTILINE
that allows you to bind them to the beginning and end of lines. The following (compiled with re.MULTILINE
) will match:
\w+\._methods_\s=\s\[$(?:\n^.+$)*\n^\]$
However, here's a slightly simplified regex that will match your examples as well:
>>> 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]"]
a source to share
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()
a source to share