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)' 

雖然,是不是真的需要在括號全部