给予:
src系列;'^(?:\d+ (\w+)|(\w+) \d+)$')可以提取一些单个子字符串(让每个字符串匹配regex)。目标:获取从源系列中提取子串的熊猫系列(即“列”)。
例如(注意,这是一个简化的例子-在实际情况下,正则表达式更复杂,即很难用单个捕获组将其重写为regex ):
src = pandas.Series(['1 s', '2 ss', 'sss 3', '4 ssss']) # source data
result = pandas.Series(['s', 'ss', 'sss', 'ssss']) # need to get我尝试了使用str.extract的直接解决方案
result = src.str.extract('^(?:\d+ (\w+)|(\w+) \d+)$')但是它返回带有两个列的DataFrame,其中每一行都有NaN和必需的子字符串:
0 1
0 s NaN
1 ss NaN
2 NaN sss
3 ssss NaN我尝试使用命名捕获组:
result = src.str.extract('^(?:\d+ (?P<field>\w+)|(?P<field>\w+) \d+)$')但我错了:
sre_constants.error:将组名“字段”重新定义为第2组
我不知道如何解决这个问题当我使用交替运算符..。
下一个问题是:当系列中的字符串与regex不匹配时,如何解决相同的问题?在这种情况下,有必要返回NaN。
更新:我找到了使用str.cat的解决方案
result = src.str.extract('^(?:\d+ (\w+)|(\w+) \d+)$')
result = result[0].str.cat(result[1], na_rep='')但这需要额外的行动..。因此,我仍然可以找到更优雅的解决方案,而不会改变regex中捕获组的数量。
发布于 2016-01-30 00:55:12
考虑对字符串的前/后部分使用非捕获组,而只使用一个捕获组。使两个非捕获组(前后)都是可选的。您不会以这种方式检测到错误的行,但它应该可以满足您的需要:
r"^(?:\d+\s+)?(\w+)(?:\s+\d+)?$"现在,您的真实数据更加复杂。考虑添加一个“查看”零宽度断言,它定义了数据的“正确”结构。这将要求字段是“有效的”,根据您已经拥有的任何正则表达式。你已经做了这项工作,你只需要把(?=.)围绕正则表达式,并将捕获组转换为非捕获组。
接下来,将所有备用情况分离到/capture/after集合中。你已经做过这件事了,你只需要整理一下。
现在用交替的方式将前集和后集统一起来,并且是一个非捕获组.将“捕获”集与交替集合和捕获组统一起来。如果可能,消除冗余(具有相同模式的两个备选方案)。
如果你的regex是这样的:
r"A(B)C|D(E)F|G(H)I|J(K)L"您可以将其转换为前瞻性模式:
r"(?=A(?:B)C|D(?:E)F|G(?:H)I|J(?:K)L)"您在“替换”之前创建一个“非捕获”:
r"(?:A|D|G|J)"和一个非捕获的“后”交替:
r"(?:C|F|I|L)"最后,捕获“捕获”替换:
r"(C|E|H|K)"把它们放在一起:
r"(?=A(?:B)C|D(?:E)F|G(?:H)I|J(?:K)L)(?:A|D|G|J)(C|E|H|K)(?:C|F|I|L)"它可能很难看,您可能希望使用嵌入的注释来记录它,但是它会起作用的。
https://stackoverflow.com/questions/35096360
复制相似问题