[英]python: re.search doesn't start at beginning of string?
我正在開發Flask API,它將以下正則表達式作為端點:
([0-9]*)((OK)|(BACK)|(X))*
這意味着我期待一系列數字,並且在這些數字之后連續多次單擊OK,BACK,X關鍵字。
我想拆分此正則表達式,並根據存在的捕獲組執行不同的操作。
我的方法如下:
endp = endp.encode('ASCII', 'ignore')
match = re.search(r"([0-9]*)", str(endp), re.I)
if match:
n = match.groups()
logging.info('nums: ' + str(n[0]))
match = re.search(r"((OK)|(BACK)|(X))*", str(endp), re.I)
if match:
s1 = match.groups()
for i in s1:
logging.info('str: ' + str(i[0]))
使用/ 12OK端點,可以很好地獲取數字,但是由於某些原因,捕獲其余關鍵字是不成功的。 我嘗試將第二個捕獲組減少到僅
match = re.search(r"(OK)*", str(endp), re.I)
我經常在s1中找到以下內容(使用簡化的正則表達式):
(None,)
最初(與其他關鍵字一起):
(None, None, None, None)
我想這意味着正則表達式模式與我的endp字符串中的任何內容都不匹配(為什么它沒有4個None?每個關鍵字1個,但是第4個是什么呢?)。 我使用正則表達式驗證器驗證了端點(也針對同一字符串的正則表達式),這對我來說似乎很好。 我知道re.match
應該從一開始就獲得匹配,因此我使用了re.search
方法,因為文檔指出它應該與字符串中的任何地方匹配。
我在這里想念什么? 請告知,我是python世界的新手。
如果要匹配至少一個組,請使用+
代替*
。
>>> endp = '/12OK'
>>> match = re.search(r"((OK)|(BACK)|(X))+", str(endp), re.I)
>>> if match:
... s1 = match.groups()
... for i in s1:
... print s1
...
('OK', 'OK', None, None)
>>> endp = '/12X'
>>> match = re.search(r"((OK)|(BACK)|(X))+", str(endp), re.I)
>>> match.groups()
('X', None, None, 'X')
請注意,表達式中有4個匹配的組,每對括號一個。 第一個匹配項是外部括號,第二個匹配項是嵌套組中的第一個。 在第二個示例中,您仍然會獲得外括號的第一個匹配項,然后最后一個是嵌套的第三個匹配項。
“(((OK)|(BACK)|(X))*”)將搜索OK或BACK或X,0次或更多次。 請注意,*表示0或更大,不超過0。上面的表達式的末尾應帶有+,而不是*,因為+表示1或更大。
確實,使用*
搜索返回`None有點令人驚訝:
>>> re.search("(OK|BACK|X)*", u'/12OK').groups()
(None,)
但這是“正確的”,因為*
匹配零個或多個,並且任何模式在任何字符串中匹配零次,這就是為什么看到None
的原因。 用+
搜索可以解決該問題:
>>> re.search("(OK|BACK|X)+", u'/12OK').groups()
('OK',)
但是現在,在/12OKOK
使用此模式進行搜索仍然只找到一個匹配項,因為+
表示一個或多個,並且在第一個OK
匹配一次。 要查找所有出現的事件,您需要使用re.findall
:
>>> re.findall("(OK|BACK|X)", u'/12OKOK')
['OK', 'OK']
有了這些發現,您的代碼將如下所示:(請注意,因為i
已經是一個字符串,所以您無需編寫i[0]
,除非您只想記錄字符串的第一個字符):
import re
endp = endp.encode('ASCII', 'ignore')
match = re.search(r"([0-9]+)", str(endp))
if match:
n = match.groups()
logging.info('nums: ' + str(n))
match = re.findall(r"(OK|BACK|X)", str(endp), re.I)
for i in match:
logging.info('str: ' + str(i))
我認為您遇到了兩個不同的問題,它們的交集比任何一個單獨導致的混亂都多。
第一個問題是您正在使用重復的組。 當重復一個組時,Python的re
庫無法捕獲多個匹配項。 與(X)+
類的模式對'XXXX'
進行匹配,即使整個字符串都將被匹配,也只會在第一組中捕獲單個'X'
。 regex
庫 (不是標准庫的一部分)可以執行多個捕獲,盡管我不確定所需的確切命令。
第二個問題是在模式中使用*
重復運算符。 您在問題頂部顯示的模式將與空字符串匹配。 顯然,在這種情況下,沒有一個人能夠捕獲任何東西(這可能就是為什么您在結果中看到很多None
條目的原因)。 您可能需要修改模式,以便它需要最少的有效文本才能算作匹配項。 使用+
代替*
可能是一種解決方案,但是我不清楚您要匹配的對象是什么,因此我無法建議特定的模式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.