将第一个括号与Python匹配
从字符串,例如将第一个括号与Python匹配,python,regex,Python,Regex,从字符串,例如 70849 mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30 我想得到第一个括号内的内容linux;Uandroid4.2.1;zh cn 我的代码如下所示: s=r'70849 mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,lik
70849 mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30
我想得到第一个括号内的内容linux;Uandroid4.2.1;zh cn
我的代码如下所示:
s=r'70849 mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30'
re.search("(\d+)\s.+\((\S+)\)", s).group(2)
但结果是最后一个括号的内容khtml,比如egecko
如何解决此问题?您可以使用否定类
\([^)]*)\
来匹配(
和之间的任何内容。
:
您遇到的主要问题是贪婪点匹配
+
模式。它获取您拥有的整个字符串,然后回溯,每次从右侧生成一个字符,试图适应后续模式。因此,它匹配最后一个括号
你可以用
^(\d+)\s[^(]+\(([^()]+)\)
看。在这里,[^(+
将匹配限制为以外的字符(
(因此,它无法抓住整行的末尾)并到达第一对括号
模式消除:
-字符串开始(注意:如果数字不出现在字符串开始处,请删除此^
锚定)^
-第1组:1个或多个数字(\d+)
-一个空白(如果它不是必需的字符,则可以删除它,因为后续的否定字符类将匹配该空格)\s
-1+个字符,而不是[^(+
(
-文字\(
(
-第2组匹配1+个字符,而不是([^()]+)
和(
)
-关闭\)
)
以下是:
你一定想说否定字符类(
[^]
)而不是否定正则表达式。我认为r'\([^()]*)”
更安全,因为它不会捕获第一个(
和最近的)之间的任何“野生”(
)
@anubhava,如果我想得到第一个数字70849([^())(\d+)\s\([^())*)
使用组(1)对吗?不,这是不正确的。没有从\s
到(
)的子模式。是的,我正在编辑我的答案,同时回复了John,但没有注意到他的正则表达式中缺少[^(]*
),这很有效!为什么我的“(\d+)\s([^()]*))'failed returns null@WiktorPlease请参见我的解释:您的模式包含一个贪婪的点匹配模式,该模式跳过了第一个括号,取而代之的是最后一个括号。我知道贪婪的影响!(\d+)\s(([^()]*)
这没有返回数字,请使用组(1)但是你的工作仅供参考:如果你删除^
,那么你必须使用重新搜索,并访问组1和组2。findall
工作,因为正则表达式锚定在字符串的开头。我有类似mi3cmui/5.11.13
和mi1sbuild/imm76d的字符串。我想得到两个类似和的组。如何解决这个问题?
^(\d+)\s[^(]+\(([^()]+)\)
import re
p = re.compile(r'^(\d+)\s[^(]+\(([^()]+)\)')
test_str = "70849 mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30"
print(p.findall(test_str))
# or using re.search if the number is not at the beginning of the string
m = re.search(r'(\d+)\s[^(]+\(([^()]+)\)', test_str)
if m:
print("Number: {0}\nString: {1}".format(m.group(1), m.group(2)))
# [('70849', 'linux;u;android4.2.1;zh-cn')]
# Number: 70849
# String: linux;u;android4.2.1;zh-cn