2012-07-22 113 views
2

考虑一个字符串s = "aa,bb11,22 , 33 , 44,cc , dd "Python(Perl型)正则表达式lookahead/lookbehind

我想s拆分为使用令牌下面的列表中regular expressions modulePython的,这是类似于Perl中提供的功能:

  1. "aa,bb11"
  2. "22"
  3. "33"
  4. "44,cc , dd "

注:

  • 我想tokenise上逗号,但只有在这些逗号有号码两侧。
  • 任何(可选)围绕我所针对的这些“数字逗号”应该在结果中删除空格。可选的空格可能不止一个空格。
  • 任何其他空格应该保留原来的字符串中。

我迄今为止最好的尝试是:

import re 

pattern = r'(?<=\d)(\s*),(\s*)(?=\d)' 
s = 'aa,bb11,22 , 33 , 44,cc , dd ' 

print re.compile(pattern).split(s) 

但这打印:

['aa,bb11', '', '', '22', ' ', ' ', '33', ' ', ' ', '44,cc , dd '] 

这是接近我想要的东西,因为在4个事情要载在列表中。我可以通过并摆脱任何空字符串和任何只包含空格/逗号的字符串,但我宁愿有一个单行的正则表达式来完成这一切。

任何想法?

回答

2

不要把对\s*捕获组:

pattern = r'(?<=\d)\s*,\s*(?=\d)' 
+0

@Ωmega再看一遍。这不是两个都做,它使用正则表达式分割。否则什么是分裂? – mVChr 2012-07-22 16:17:44

+0

@megamega split是一个正则表达式,但findall也是如此。斯普利特是被要求的。经过两次测试,无论两者是否“足够快”,即使调整了较慢的编译时间,您的方法也会比mVChr更慢。 – 2012-07-22 16:55:48

0

别组\ S *,他们不会被捕获并写入输出:

>>> import re 
>>> s = 'aa,bb11,22 , 33 , 44,cc , dd ' 
>>> re.compile(r'(?<=\d)(\s*),(\s*)(?=\d)').split(s) 
['aa,bb11', '', '', '22', ' ', ' ', '33', ' ', ' ', '44,cc , dd '] 
>>> re.compile(r'(?<=\d)\s*,\s*(?=\d)').split(s) 
['aa,bb11', '22', '33', '44,cc , dd '] 
0

你不需要使用正则表达式和分割 - 这太复杂了。看到这个>>

import re 
s = "aa,bb11,22 , 33 , 44,cc , dd " 
result = re.findall(ur"(?:^\s*|(?<=\d)\s*,\s*)(.*?)(?=\s*,\s*\d|\s*$)", s) 
print(result) 

输出:

['aa,bb11', '22', '33', '44,cc , dd'] 

测试它here

+0

如果你想在最后一场比赛中保留空白字符(我相信你不这么做),那么只用'$'替换正则表达式中的'\ s * $'。类似的改变适用于第一场比赛中领先的空格字符(在你的例子中没有),所以如果你想保留这些空格,那么只用'^'替换'^ \ s *'。 – 2012-07-22 15:59:31

0

您正在使用捕获括号中的额外空白就是由两个(\s*)可以使用非捕获括号这样捕获:

r'(?<=\d)(?:\s*),(?:\s*)(?=\d)' 

虽然,是不是真的需要在括号全部