Python 2.7.1 我正在尝试使用python正则表达式来提取模式中的单词
我有一些看起来像这样的字符串
someline abc
someother line
name my_user_name is valid
some more lines
我想提取单词“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>
如何立即提取my_user_name?
答案 0 :(得分:96)
你需要从正则表达式中捕获。如果找到该模式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'
答案 1 :(得分:41)
您可以使用匹配的组:
p = re.compile('name (.*) is valid')
e.g。
>>> 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']
在这里,我使用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'
正如评论中所提到的,你可能想让你的正则表达式变得非贪婪:
p = re.compile('name (.*?) is valid')
只能选择'name '
和下一个' is valid'
之间的内容(而不是让正则表达式在您的论坛中选择其他' is valid'
。
答案 2 :(得分:15)
您可以使用以下内容:
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')
答案 3 :(得分:9)
您需要capture group。
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.
答案 4 :(得分:6)
也许这会更短,更容易理解:
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'
答案 5 :(得分:4)
在Python 3.6及更高版本中,您可以index进入匹配对象,而无需使用group()
,例如:
>>> import re
>>> s = 'name my_user_name is valid'
>>> match = re.search('name (.*) is valid', s)
>>> match[0] # the entire match
'name my_user_name is valid'
>>> match[1] # the first parenthesized subgroup
'my_user_name'
答案 6 :(得分:3)
这是一种无需使用组(Python 3.6或更高版本)的方法:
>>> re.search('2\d\d\d[01]\d[0-3]\d', 'report_20191207.xml')[0]
'20191207'
答案 7 :(得分:1)
似乎您实际上是在尝试提取名称副,只是找到一个匹配项。在这种情况下,为您的比赛设置跨度索引会有所帮助,我建议您使用re.finditer
。作为快捷方式,您知道正则表达式的name
部分的长度为5,而is valid
的长度为9,因此您可以对匹配的文本进行切片以提取名称。
注意-在您的示例中,s
看起来像是带换行符的字符串,因此以下是假设。
## covert s to list of strings separated by line: s2 = s.splitlines() ## find matches by line: for i, j in enumerate(s2): matches = re.finditer("name (.*) is valid", j) ## ignore lines without a match if matches: ## loop through match group elements for k in matches: ## get text match_txt = k.group(0) ## get line span match_span = k.span(0) ## extract username my_user_name = match_txt[5:-9] ## compare with original text print(f'Extracted Username: {my_user_name} - found on line {i}') print('Match Text:', match_txt)
答案 8 :(得分:0)
您还可以使用捕获组(?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
答案 9 :(得分:0)
我通过 google 找到了这个答案,因为我想将带有 多个组的re.search()
结果直接解压到多个变量中。虽然这对某些人来说可能很明显,但对我来说却不是,因为我过去总是使用 group()
,所以也许它可以帮助将来也不知道 group*s*()
的人。
s = "2020:12:30"
year, month, day = re.search(r"(\d+):(\d+):(\d+)", s).groups()