我正在尝试从cscope符号搜索中标记化结果字符串,该搜索由一些由空格分隔的字段组成:
/path/including whitespace/to/file.ext function_name line_number <any_content>
使用正则表达式。
我正在使用python,我试过的正则表达式是:
r'^(?P<File>[\w\W\s]+?)[\s]{1}(?P<Function>[\w]+[\s]{1}(?P<Linenum>[0-9]+)[\s]{1})(?P<Content>[\w\W\s]+)'
它不起作用,我觉得找出解决方案很难,因为该字符串中有太多的空格。请注意,路径组(文件)和内容组(内容)都可以包含空格。我似乎无法绕过它。
更新
正确的输出将是这样的字符串列表:
['/ path /包括whitespace / to / file.ext','function_name','line_number','']
所有文件名都带有扩展名,例如.cpp。
答案 0 :(得分:1)
根据.cpp作为扩展程序的更新:
>>> import re
>>> line = '/path/including whitespace/to/file.cpp function_name 1234 <any_content>'
>>> r = re.match(r'(?P<File>.+?\.cpp) (?P<Function>\w+) (?P<Linenum>[0-9]+) (?P<Content>.*)$', line)
>>> r.groupdict()
{'Function': 'function_name', 'Linenum': '1234', 'Content': '<any_content>', 'File': '/path/including whitespace/to/file.cpp'}
>>> r.groups()
('/path/including whitespace/to/file.cpp', 'function_name', '1234', '<any_content>')
以上假设“.cpp”仅在结尾处仅出现在文件名中一次。如果这是可以接受的,那么上面应该相当稳健。
如果您有多个扩展程序,例如.cpp,.h和.c,然后:
>>> r = re.match(r'(?P<File>.+?\.(?:cpp|h|c)) (?P<Function>\w+) (?P<Linenum>[0-9]+) (?P<Content>.*)$', line)
假设是相同的:扩展后跟空格在结尾的文件名中只出现一次。文件名匹配是非贪婪的((?P<File>.+?\.(?:cpp|h|c))
),因此看起来像扩展名的内容可以出现在内容部分中而不会干扰匹配。
答案 1 :(得分:1)
这个正则表达式适用于样本:
st='/path/including whitespace/to/file.ext function_name 1234 <any_content>'
pat=re.compile(r'^(?P<Path>.+\.\S{,3})\s+(?P<Function>\w+)\s+(?P<Linenum>\d+)\s+(?P<Contents>.+)$')
m=pat.match(st)
print(m.groupdict())
print(list(m.group(1,2,3,4)))
打印:
{'Contents': '<any_content>', 'Function': 'function_name', 'Path': '/path/including whitespace/to/file.ext', 'Linenum': '1234'}
['/path/including whitespace/to/file.ext', 'function_name', '1234', '<any_content>']
我的SCO内存模糊,但<any_content>
可能是多行?如果是这样,您可以使用re.S来匹配不同的行:
st='''\
/path/including whitespace/to/file.h function_name 1234 <any_content .cpp>|
/path/including whitespace/to/file.cpp function_name 1234 <any_content
multiline>'''
pat=re.compile(r'^(?P<Path>.+\.\S{,3})\s+(?P<Function>\w+)\s+(?P<Linenum>\d+)\s+(?P<Contents>.+)', re.S)
for line in re.split(r'\|\n', st):
m=pat.match(line)
print(line)
print(list(m.group(*['Path', 'Function', 'Linenum', 'Contents'])), '\n')
打印:
/path/including whitespace/to/file.h function_name 1234 <any_content .cpp>
['/path/including whitespace/to/file.h', 'function_name', '1234', '<any_content .cpp>']
/path/including whitespace/to/file.cpp function_name 1234 <any_content
multiline>
['/path/including whitespace/to/file.cpp', 'function_name', '1234', '<any_content \n multiline>']
您可能希望configure cscope不打印可能发现问题的路径。