我正在使用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个Nones?每个关键字1个,但第4个是什么?)。我使用正则表达式验证器验证了我的端点(对同一个字符串的正则表达式),对我来说似乎很好。我知道re.match
应该从头开始匹配,因此我使用re.search
方法,因为documentation指出它应该匹配字符串中的任何位置。
我在这里缺少什么?请指教,我是蟒蛇世界的初学者。
答案 0 :(得分:0)
如果您想要匹配至少一个群组,请使用+
代替*
。
>>> 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个匹配的组,每对括号一个。第一个匹配是外括号,第二个匹配是第一个嵌套组。在第二个例子中,你仍然得到外括号的第一个匹配,然后最后一个是嵌套的第三个匹配。
答案 1 :(得分:0)
"((OK)|(BACK)|(X))*"将搜索OK或BACK或X,0或更多次。请注意,*表示0或更多,不超过0.上面的表达式应该在结尾处+不*,+表示1或更多。
答案 2 :(得分:0)
确实用*
搜索返回“无:
>>> 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[0]
,因为i
已经是一个字符串,除非您只想记录第一个字符串字符串):
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))
答案 3 :(得分:0)
我认为你有两个不同的问题,他们的交集导致了比他们自己造成的更多混乱。
第一个问题是您正在使用重复的组。 Python的re
库在重复组时无法捕获多个匹配项。与(X)+
类型的模式匹配'XXXX'
将只捕获第一组中的单个'X'
,即使整个字符串将匹配。 regex
library(不是标准库的一部分)可以进行多次捕获,但我不确定所需的确切命令。
第二个问题是在模式中使用*
重复运算符。您在问题顶部显示的模式将匹配空字符串。显然,在这种情况下,没有一个gropus会捕获任何东西(这可能就是你在结果中看到很多None
个条目的原因)。您可能需要修改模式,以便需要一些最小数量的有效文本作为匹配项。使用+
代替*
可能是一种解决方案,但我不清楚您想要匹配哪些内容,因此我无法建议特定的模式。