从这个例子:
>>> re.split('(\W)', 'foo/bar spam\neggs')
['foo', '/', 'bar', ' ', 'spam', '\n', 'eggs']
是否有一种直接的方法将捕获组与拆分的右侧或左侧部分相关联?例如。使用相同的正则表达式/捕获组,但屈服:
['foo', '/bar', ' spam', '\neggs']
或可选
['foo/', 'bar ', 'spam\n', 'eggs']
我确信你可以通过更改实际的正则表达式来实现它,但这不是重点(我们可以修改示例以使匹配变得更复杂,所以这真的很痛苦无法重新使用它们并向右或向左推动它们。
不幸的是,它似乎使它成为非捕获组只是从匹配中删除相应的字符:
>>> re.split('(?:\W)', 'foo/bar spam\neggs')
['foo', 'bar', 'spam', 'eggs']
通过另一个示例,考虑您是否有来自行为不当的CSV文件的文本。每行只有一个实际的逗号可以拆分,但是偶然某些行在其中一个字段中也有逗号。幸运的是,非分裂逗号后面总是有一个空格。
csv_data = [
'Some good data,Id 5',
'Some bad data, like, really bad, dude,Id 6'
]
这种情况下的目标是将其处理为:
[['Some good data', 'Id 5'],
['Some bad data, like, really bad, dude', 'Id 6']]
通过使用简单的re.split
。
使用map(lambda x: re.split(",(?:\S)", x), csv_data)
生成
[['Some good data', 'd 5'],
['Some bad data, like, really bad, dude', 'd 6']]
并使用map(lambda x: re.split(",(\S)", x), csv_data)
生成
[['Some good data', 'I', 'd 5'],
['Some bad data, like, really bad, dude', 'I', 'd 6']]
那么re.split
的通用方法对于这两种情况都有同样的作用吗?基本上我可以在函数中包装,比如
def my_split(regex_chars, my_strs):
return map(lambda x: re.split(...regex_chars..., x), my_strs)
这两个
my_split(r'(\W)', ['foo/bar spam\neggs'])
和
my_split(r',(\S)', csv_data)
每个都从上面返回预期的输出。
注意:仅re
显示这是不可能的,但根据是否分割,可能会混合使用regex
和re
是零宽度还是没有。
答案 0 :(得分:3)
不,这是不可能的。我不知道任何支持此类事情的正则表达式引擎。拆分意味着拆分:您可以保留拆分器或者您可以丢弃它,但是您不能将它与拆分之间的碎块混在一起,因为分隔符与它分离的东西不同。
使用regex
模块,您可以相当简单地完成它,但它确实需要更改原始正则表达式:
>>> regex.split('(?=\W)', 'foo/bar spam\neggs', flags=regex.V1)
['foo', '/bar', ' spam', '\neggs']
与内置re
模块不同,regex
模块允许拆分零宽度匹配,因此您可以使用前瞻分割在下一个字符与\W
匹配的位置。< / p>
在您在编辑中添加的示例中,即使使用普通re
也可以使用前瞻功能,因为拆分器不是零宽度:
>>> map(lambda x: re.split(",(?=\S)", x), csv_data)
[['Some good data', 'Id 5'],
['Some bad data, like, really bad, dude', 'Id 6']]
答案 1 :(得分:2)
在这种情况下,您可以使用基于负面预测的正则表达式,如下所示。
>>> csv_data = [
'Some good data,Id 5',
'Some bad data, like, really bad, dude,Id 6'
]
>>> [re.split(r',(?!\s)', i) for i in csv_data]
[['Some good data', 'Id 5'], ['Some bad data, like, really bad, dude', 'Id 6']]
,(?!\s)
匹配所有逗号后面都没有空格字符。根据匹配的逗号分割将为您提供所需的输出。