将第一个括号与Python匹配

时间:2016-05-06 09:31:22

标签: python regex

来自

等字符串
70849   mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30

我想获得第一个带括号的内容linux;u;android4.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,likegecko

如何解决这个问题?

2 个答案:

答案 0 :(得分:1)

您可以使用否定的课程\(([^)]*)\)来匹配()之间的任何内容:

>>> s=r'70849  mozilla/5.0(linux;u;android4.2.1;zh-cn)applewebkit/534.30(khtml,likegecko)version/4.0mobilesafari/534.30'

>>> m = re.search(r"(\d+)[^(]*\(([^)]*)\)", s)
>>> print m.group(1)
70849
>>> print m.group(2)
linux;u;android4.2.1;zh-cn

答案 1 :(得分:1)

您遇到的主要问题是贪婪点匹配.+模式。它抓住你拥有的整个字符串,然后回溯,一次从右边产生一个字符,试图适应后续的模式。因此,它匹配 last 括号。

您可以使用

^(\d+)\s[^(]+\(([^()]+)\)

请参阅regex demo。在这里,[^(]+将匹配限制为(以外的字符(因此,它不能抓住整行直到最后)并转到第一对括号。

模式expalantion:

  • ^ - 字符串开头(注意:如果该数字不显示在字符串的开头,请删除此^锚点)
  • (\d+) - 第1组:1位或更多位数
  • \s - 一个空格(如果它不是必需的字符,则可以删除它,因为后续的否定字符类将匹配该空格)
  • [^(]+ - (
  • 以外的1个字符
  • \( - 文字(
  • ([^()]+) - 第2组匹配除()以外的1 +个字符
  • \) - 关闭)

Regular expression visualization

Debuggex Demo

这是IDEONE demo

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