2012-09-25 72 views
0

我需要在文本文檔中查找價格。我的代碼如下所示:Python重新捕獲每個單詞的一個匹配

sentence = "This is test text $25,000 $25,000$20,000 $30" 
pattern = re.compile(ur'[$€£]?\d+([.,]\d+)?', re.UNICODE | re.MULTILINE | re.DOTALL) 
print pattern.findall(sentence) 

期望的結果是:

['$25,000', '$30'] 

我並不需要包括$ 25,000 $ 20,000結果becouse這不是我的任務有效的結果。我只需要全字匹配。

,但我得到這個結果:

['$25,000', '$25,000', '$20,000', '$30'] 

如何重寫我的正則表達式來僅包含由空格或標點符號隔開的價格?

回答

1

嘗試以下操作:

ur'(?<!\S)[€£$]?\d+(?:[.,]\d+)?(?!\S)' 

我加負斷言(?<!\S)(?!\S),它們分別表示「如果前面有非空格則不匹配」和「如果後面跟非空格則不匹配」。

測試:

>>> sentence = "$1234 $56$78.90 This is test text $25,000 $25,000$20,000 $30" 
>>> pattern = re.compile(ur'(?<!\S)[€£$]?\d+(?:[.,]\d+)?(?!\S)', re.UNICODE | re.MULTILINE | re.DOTALL) 
>>> print pattern.findall(sentence) 
['$1234', '$25,000', '$30'] 

如果你想允許某些非空格字符之前或比賽結束後,由[^\s<chars>]其中<chars>是要允許字符替換\S。例如:

ur'(?<![^\s:])[€£$]?\d+(?:[.,]\d+)?(?![^\s,.])' 

允許通過一個:進行之前和之後,.圖案:

>>> sentence = "$1234 $56$78.90 This is test text:$25,000. $45. $25,000$20,000 $30" 
>>> print pattern.findall(sentence) 
['$1234', '$25,000', '$45', '$30'] 
+0

你可以請添加。,:作爲分隔符嗎?價格可以被空白或標點符號(。,:)包圍。例如:「這是測試文本。$ 25,000」需要返回$ 25,000 – twoface88

+1

然後它變得模糊! 「$ 25,000 $ 25,000'會產生'000',因爲它是一個以','開頭的數字序列。 – nneonneo

+0

如果我們從分隔符中刪除「,」會怎麼樣?只要 」。」和「:」 – twoface88

1

這是接近我可以得到它(儘管有許多人有更多的正則表達式的技巧比我):

pattern = re.compile(ur'(?:^|\s)[$€£]?\d+(?:[.,]\d+)?(?=\s|$)', re.UNICODE | re.MULTILINE | re.DOTALL) 
print pattern.findall(sentence) # [' $25,000', ' $30'] 
+0

爲什麼會出現空白的結果? (?:...)不包含組到結果..對嗎? – twoface88

+1

@ twoface88 - 有點。 '(:?...)'表示沒有創建新的組。但是,這部分比賽仍然包括在內。更爲標準的方法是使用lookbehind斷言:'(?<= ...)',但是在Python中,lookbehind必須是一個常量,其長度爲(?<=^| \ s)'isn'噸。 (它的長度爲0或1),所以很不幸,這不起作用。後處理'findall'很容易,但''[pattern.findall(句子)]中的[x.strip()']會執行此操作。 – mgilson

+0

puntuation怎麼樣?如果是這樣的話:「這是測試文本$ 25,000」$ 25,000未找到 – twoface88