用于标记空格分隔字符串的正则表达式

时间:2014-01-05 22:31:45

标签: python regex

我正在尝试从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。

  • 我无法修改 删除空格的路径(不是我自己的决定)。

2 个答案:

答案 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不打印可能发现问题的路径。