我有一个特殊的用例,我还不知道如何覆盖。我想基于field_name / field_length剖析字符串。为此,我定义了一个这样的正则表达式:
'(?P<%s>.{%d})' % (field_name, field_length)
所有领域都会重复这一过。
我还有一个正则表达式,用于删除每个字段右侧的空格:
self.re_remove_spaces = re.compile(' *$')
这样我可以得到这样的每个字段:
def dissect(self, str):
data = { }
m = self.compiled.search(str)
for field_name in self.fields:
value = m.group_name(field_name)
value = re.sub(self.re_remove_spaces, '', value)
data[field_name] = value
return data
我必须对数百万个字符串执行此处理,因此它必须高效。
令我恼火的是,我宁愿使用compiled.sub
代替compiled.search
一步完成解剖+空间移除,但我不知道该怎么做。
具体来说,我的问题是:
如何在Python正则表达式中将它与命名组结合使用正则表达式替换?
答案 0 :(得分:4)
我认为每个字段都在字符串中彼此相邻,就像在表格中一样,例如:
name description license
python language opensource
windows operating system proprietry
因此,假设您事先知道每个字段的长度,您可以更简单地完成它,而根本不使用正则表达式。 (顺便说一句,str
不是变量的好名字,因为它与内置str
类型冲突了)
def dissect(text):
data = {}
for name, length in fields:
data[name] = text[:length].rstrip()
text = text[length:]
return data
然后,如果fields = [('lang', 9), ('desc', 19), ('license', 12)]
:
>>> self.dissect('python language opensource')
{'lang': 'python', 'license': 'opensource', 'desc': 'language'}
这是你正在尝试做的吗?
答案 1 :(得分:0)
为什么在您可以直接匹配所需的部分时使用sub
?
您可以使用以下内容:
(?P<name>.{0,N}(?<! ))
但如果匹配必须完全N
长,您可以使用前瞻,例如:
(?=(?P<name>.{0,N}(?<! ))).{N}
如果这比使用额外的修剪更好的表现是值得怀疑的。你可以尝试一下,让我们知道。
如果匹配只是空格,这些表达式将不起作用,而前面的字符也是空格。如果您需要该案例,您可以在小组末尾添加|
:
(?P<name>.{0,N}(?<! )|)