1

为什么下一个正则表达式在“a”和“b”之间返回空字符串?

In [48]: pat = re.compile(".*?(?=,|$)")

In [49]: it = pat.findall('a,b')

In [50]: it
Out[50]: ['a', '', 'b', '']

如何提取逗号之间的子字符串?

编辑:我很好奇如何使用正则表达式来做到这一点。

编辑:正则表达式应该成功地在此输入“,”中提取树空字符串。

4

3 回答 3

2
  • .*?first 匹配a,因为下一个字符是 a ,
  • 正则表达式引擎现在位于,.
  • 现在,.*?匹配之前的空字符串,(因为星号允许零长度匹配)。
  • 正则表达式引擎在零长度匹配后前进一个字符(它必须这样做,否则它将永远卡在这里)。
  • .*?现在匹配b,因为我们在字符串的末尾。
  • 正则表达式引擎现在位于字符串的末尾。
  • .*?匹配字符串结尾之前的空字符串。
  • 弦已用尽。正则表达式引擎结束。

最好的解决方案是简单地用逗号分隔。

如果您坚持使用正则表达式,它会更复杂一些,因为(根据docsre.findall()包括空匹配项,除非它们触及另一个匹配项的开头。这意味着我们必须使用积极的后向断言而不是您使用的前瞻断言。

这反过来意味着我们不能在同一个断言中检查定界符和字符串起始锚点,因为 Python 不允许在lookbehinds 中使用可变宽度的正则表达式(叹气)。但有可能是这样的:

>>> re.findall("(?:^|(?<=,))[^,]*", "a,b,,c")
['a', 'b', '', 'c']
于 2013-11-05T18:19:49.253 回答
1

你可以这样做:

st='a,b,   c  , d, eeeee'
data=[e.strip() for e in st.split(',')]

print data
# ['a', 'b', 'c', 'd', 'eeeee']

或使用 csv:

for line in csv.reader(st.splitlines()):
    print line
# ['a', 'b', '   c  ', ' d', ' eeeee']  # strip as you please

或正则表达式:

print re.findall(r'([^,]+)(?:,|$)', st) 
# ['a', 'b', '   c  ', ' d', ' eeeee']

编辑

这可以满足您使用正则表达式的要求:

>>> re.findall(r'[^,]+|,\s*,', 'a,b,   c  ,, d, eeeee')
['a', 'b', '   c  ', ',,', ' d', ' eeeee']
于 2013-11-05T18:18:49.993 回答
0

I think the problem is that your entire regex consist of "optional" character consumption before a lookahead assertion.

As the match position advances it can either match something or nothing.
When it matches nothing, the array fills with a ''.

So a,b matches 'a', '', 'b', ''
where the final '' is the end of string (just as .*$ matches the empty string)

于 2013-11-05T19:21:33.480 回答