web-dev-qa-db-ja.com

Pythonパターンマッチの抽出

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を今すぐ抽出するにはどうすればよいですか?

79
Kannan Ekanath

正規表現からキャプチャする必要があります。パターンの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'
101
UltraInstinct

一致するグループを使用できます:

p = re.compile('name (.*) is valid')

例えば.

>>> 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'を正規表現にピックアップさせるのではなく)。

41
mgilson

次のようなものを使用できます。

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')
15
Apalala

キャプチャグループ が必要です。

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.
9
Henry Keiter

多分それは少し短く、理解しやすいです:

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'
6
John

Python 3.6+では、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'
4
Eugene Yarmash

グループを使用せずにそれを行う方法は次のとおりです(Python 3.6以降):

>>> re.search('2\d\d\d[01]\d[0-3]\d', 'report_20191207.xml')[0]
'20191207'
3
wolfovercats

キャプチャグループ(?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
0
Ryan Stefan