我试图从csv文件中解析一些行来提取一系列数字。有两种可能的格式,单独的数字,或嵌入在较长代码中的数字。
这是我正在做的事情的代码示例,以及出了什么问题:
# regex works
>>> re.search('^(\d+)$', '5755').group(0, 1)
('5755', '5755')
# regex works with capturing group inside non-capturing group
>>> re.search('(?:^(\d+)$)', '5755').group(0, 1)
('5755', '5755')
# regex does not work as second of two non-capturing groups
>>> re.search('(?:\$SK-*(\d+)[-K])|(?:^(\d+)$)', '5755').group(0, 1)
('5755', None)
# the other regex of the pair works
>>> re.search('(?:\$SK-*(\d+)[-K])|(?:^(\d+)$)', '11$SK-2301-K13').group(0, 1)
('$SK-2301-', '2301')
# the regex works as the first of two non-capturing groups
>>> re.search('(?:^(\d+)$)|(?:\$SK-*(\d+)[-K])', '5755').group(0, 1)
('5755', '5755')
正如您所看到的,正则表达式本身可以正常工作,或者包含在(?...)中,但是当与另一个正则表达式结合使用时,两个正则表达式中的第二个正则表达式的组停止工作,即使搜索返回一个匹配对象。但是,如果我然后交换管道连接的正则表达式的顺序,第一个仍然可以工作,无论它是哪个正则表达式。
要清楚的是,当我将两个正则表达式与管道('|')组合在一起时,第一个上的组将起作用,但第二个上的组将不起作用。
为什么会这样?我该如何解决这个问题?
答案 0 :(得分:1)
问题的原因是,对子群如何运作的直观理解并不是他们在实践中如何运作。
我将扩展您的问题的两个不同评论正确指出。 子组未被捕获编号,而是在创建/解析正则表达式时被修复。例如:
re.search('match:(foo)','match:foo').group(1)
将是
('foo')
因为第一个捕获组是(foo)
。类似地
re.search('match:(foo)(bar)','match:foobar').group(1,2)
将是
('foo','bar')
由于第一和第二个捕获组是(foo)
和(bar)
,并且每个捕获组都匹配并捕获。
以
等模式match:(?:(foo)|(bar))
(foo)
和(bar)
仍然是第一个和第二个捕获组,即使其中只有一个可以捕获,感谢OR |
。
re.search('match:(?:(foo)|(bar))','match:foo').group(1,2)
re.search('match:(?:(foo)|(bar))','match:bar').group(1,2)
将输出
('foo', None)
(None, 'bar')
因此,您需要在代码中添加一些逻辑,以检查哪些捕获组具有内容并返回该内容。