2017-05-17 133 views
1

我想捕獲一個字x周圍沒有空格的n個單詞。我需要每個單詞的捕獲組。我可以通過以下方式(X之後的話在這裏)實現這一點:正則表達式,貪婪的量詞多個捕獲組

import regex 
n = 2 
x = 'beef tomato chicken trump Madonna' 
right_word = '\s+(\S+)' 
regex_right = r'^\S*{}\s*'.format(n*right_word) 
m_right = regex.search(regex_right, x) 
print(m_right.groups()) 

所以當x =「牛肉番茄雞王牌麥當娜」,N = 2,regex_right = '^\S*\s+(\S+)\s+(\S+)\s*',我也得到含有「番茄」兩個捕獲組和'雞'。然而,如果n = 5,我不會捕獲任何不是我所尋找的行爲。對於n = 5,我想捕捉所有的話'牛肉'的權利。

我已經使用了貪心量詞

regex_right = r'^\S*(\s+\S+){,n}\s*' 

嘗試,但我只得到一個組(最後一個字),無論我有多少場比賽得到(而且我得到的空格以及..)。

我終於嘗試使用regex.findall,但我不能限制它的n個單詞,但必須指定字符數量?

任何人都可以幫忙嗎?


Wiktor幫助了我(見下文)謝謝。但我有一個額外的問題

如果 x ='牛肉,西紅柿,雞,王牌麥當娜' 我不知道如何捕捉沒有逗號?我不想讓羣組成爲'西紅柿',

+0

您是否在尋找(https://regex101.com/r/dMNijJ/1) – Jan

回答

5

由於模式與輸入字符串不匹配,所以您沒有使用第一種方法匹配所有這些單詞。你需要用(?:...)?封閉它使right_word模式可選

import re 
x = 'beef tomato chicken trump Madonna' 
n = 5 
right_word = '(?:\s+(\S+))?' 
regex_right = r'^\S*{}'.format(n*right_word) 
print(regex_right) 
m_right = re.search(regex_right, x) 
if m_right: 
    print(m_right.groups()) 

Python demo

第二種方法僅適用於PyPi正則表達式模塊,因爲Python re不保留重複捕獲,一旦量化捕獲組在相同的匹配迭代中再次匹配子串,其值將被重寫。

>>> right_word = '\s+(\S+)' 
>>> n = 5 
>>> regex_right = r'^\S*(?:\s+(\S+)){{1,{0}}}'.format(n) 
>>> result = [x.captures(1) for x in regex.finditer(regex_right, "beef tomato chicken trump Madonna")] 
>>> result 
[['tomato', 'chicken', 'trump', 'Madonna']] 
>>> print(regex_right) 
^\S*(?:\s+(\S+)){1,5} 

注意^\S*(?:\s+(\S+)){1,5}具有捕獲組#1與該{1,5}限制性量詞量化的量化非捕獲組內,並且由於PyPI中的正則表達式跟蹤反覆捕獲組捕獲的所有的值,它們都是這裏可以通過.captures(1)進入。您可以測試該功能與.NET regex testerenter image description here

+1

謝謝你Wiktor!我不明白1)我可以在一個非變量擴展名'(?:)'中捕獲2)我也沒有想到通過在前面添加一個? –

+0

我在上面增加了一個問題:-D –

+0

然後使用[像這樣](https://regex101.com/r/RyQ8sE/1),使用'(?:\ s +(\ w +),?)? '而不是'(?:\ s +(\ S +))?'。甚至['(?:\ s +(\ w +)[^ \ w \ s] *)?'](https://regex101.com/r/RyQ8sE/2)來處理任何標點符號。 –

0

您得到了正確的方法。然而,正則表達式不能做你要求的東西。每次您的捕獲組捕獲另一個模式時,先前的內容將被替換。這就是爲什麼你的捕捉組只返回最後捕獲的模式。
您可以輕鬆匹配n個單詞,但無法明確寫入每個捕獲組,而無法單獨捕獲它們。

+0

給我看,然後一個例子... – Gawil

+0

[**這**?] @Jan,我認爲'\ G'不會精確匹配的數量。那麼,我們當然可以「修剪」結果列表。 –

+0

是的,請參閱https://regex101.com/r/dMNijJ/2 – Jan