Python提取模式匹配

Kan*_*ath 96 python regex

Python 2.7.1我试图使用python正则表达式来提取模式中的单词

我有一些看起来像这样的字符串

someline abc
someother line
name my_user_name is valid
some more lines
Run Code Online (Sandbox Code Playgroud)

我想提取单词"my_user_name".我做的事情

import re
s = #that big string
p = re.compile("name .* is valid", re.flags)
p.match(s) #this gives me <_sre.SRE_Match object at 0x026B6838>
Run Code Online (Sandbox Code Playgroud)

如何立即提取my_user_name?

Ult*_*nct 125

你需要从正则表达式捕获.search对于模式,如果找到,则使用检索字符串group(index).假设执行了有效检查:

>>> p = re.compile("name (.*) is valid")
>>> result = p.search(s)
>>> result
<_sre.SRE_Match object at 0x10555e738>
>>> result.group(1)     # group(1) will return the 1st capture.
'my_user_name'
Run Code Online (Sandbox Code Playgroud)

  • 有点迟了,但既有也有.`group(0)`返回匹配的文本,而不是第一个捕获组.代码注释是正确的,而您似乎混淆了捕获组和匹配.`group(1)`返回第一个捕获组. (26认同)
  • 你确定第一场比赛不是'group(0)`吗? (21认同)
  • 此类问题应该迫使文档重新编写 (7认同)
  • @IanG对不起,我将更新我的答案。顺便说一句,使用标准的python REPL,最后的结果存储在名为“ _”的特殊变量中。在其他任何地方都无效。 (2认同)

mgi*_*son 44

您可以使用匹配的组:

p = re.compile('name (.*) is valid')
Run Code Online (Sandbox Code Playgroud)

例如

>>> import re
>>> p = re.compile('name (.*) is valid')
>>> s = """
... someline abc
... someother line
... name my_user_name is valid
... some more lines"""
>>> p.findall(s)
['my_user_name']
Run Code Online (Sandbox Code Playgroud)

在这里我使用re.findall而不是re.search获取所有实例my_user_name.使用时re.search,您需要从匹配对象上的组中获取数据:

>>> p.search(s)   #gives a match object or None if no match is found
<_sre.SRE_Match object at 0xf5c60>
>>> p.search(s).group() #entire string that matched
'name my_user_name is valid'
>>> p.search(s).group(1) #first group that match in the string that matched
'my_user_name'
Run Code Online (Sandbox Code Playgroud)

正如评论中提到的,您可能希望使您的正则表达式非贪婪:

p = re.compile('name (.*?) is valid')
Run Code Online (Sandbox Code Playgroud)

只接收'name '下一个和下一个之间的东西' is valid'(而不是让你的正则表达式' is valid'在你的小组中拿起其他东西.

  • 可能需要非贪婪的匹配...(除非用户名可以是多个单词......) (2认同)

Apa*_*ala 16

你可以使用这样的东西:

import re
s = #that big string
# the parenthesis create a group with what was matched
# and '\w' matches only alphanumeric charactes
p = re.compile("name +(\w+) +is valid", re.flags)
# use search(), so the match doesn't have to happen 
# at the beginning of "big string"
m = p.search(s)
# search() returns a Match object with information about what was matched
if m:
    name = m.group(1)
else:
    raise Exception('name not found')
Run Code Online (Sandbox Code Playgroud)


Hen*_*ter 10

你想要一个捕获组.

p = re.compile("name (.*) is valid", re.flags) # parentheses for capture groups
print p.match(s).groups() # This gives you a tuple of your matches.
Run Code Online (Sandbox Code Playgroud)


Joh*_*ohn 8

也许这有点短,更容易理解:

import re
text = '... someline abc... someother line... name my_user_name is valid.. some more lines'
>>> re.search('name (.*) is valid', text).group(1)
'my_user_name'
Run Code Online (Sandbox Code Playgroud)


Eug*_*ash 8

您可以使用组(用'('和表示')')捕获字符串的一部分。然后,match对象的group()方法为您提供组的内容:

>>> import re
>>> s = 'name my_user_name is valid'
>>> match = re.search('name (.*) is valid', s)
>>> match.group(0)  # the entire match
'name my_user_name is valid'
>>> match.group(1)  # the first parenthesized subgroup
'my_user_name'
Run Code Online (Sandbox Code Playgroud)

在Python 3.6+中,您也可以索引到match对象中,而不是使用group()

>>> match[0]  # the entire match 
'name my_user_name is valid'
>>> match[1]  # the first parenthesized subgroup
'my_user_name'
Run Code Online (Sandbox Code Playgroud)


wol*_*ats 6

这是一种无需使用组(Python 3.6或更高版本)的方法:

>>> re.search('2\d\d\d[01]\d[0-3]\d', 'report_20191207.xml')[0]
'20191207'
Run Code Online (Sandbox Code Playgroud)


小智 5

您还可以使用捕获组(?P<user>pattern)并像访问字典一样访问该组match['user']

string = '''someline abc\n
            someother line\n
            name my_user_name is valid\n
            some more lines\n'''

pattern = r'name (?P<user>.*) is valid'
matches = re.search(pattern, str(string), re.DOTALL)
print(matches['user'])

# my_user_name
Run Code Online (Sandbox Code Playgroud)