正規表現のパターン
今までは正規表現のパターンに普通の文字列でした。
Helが正規表現のパターンで分かりやすいです。呪文のような正規表現のパターンがたくさんあります。
文字 |
説明 |
\d |
任意の数字 漢数字を含む
re.findall('\d', 'abc123de567fあい')
→['1', '2', '3', '5', '6', '7']
\dと[0-9]は同じと説明しているサイトがありますが、本当か?
re.findall('[0-9]', 'abc123de567fあい)
→['1', '2', '3']
半角文字しか一致しません。 \dと[0-9]はまったく同じではありません。
|
\D |
任意の数字以外 漢数字を含む
re.findall('\D', 'abc123de567fあい')
→['a', 'b', 'c', 'd', 'e', 'f', 'あ', 'い']
¥Dは[^0-9]と同じか? re.findall('[^0-9]', 'abc123de567fあい')
→['a', 'b', 'c', 'd', 'e', '5', '6', '7', 'f', 'あ', 'い']
半角文字しか一致しません。 \Dと[0-9]はまったく同じではありません。
|
\s |
タブや改行文字 [\t\n\r\f\v]
re.findall('\s','ab\t1234cd56\n')
→['\t', '\n']
|
\S |
タブや改行文字以外[^\t\n\r\f\v]
re.findall('\S','ab\t1234cd56\n')
→['a', 'b', '1', '2', '3', '4', 'c', 'd', '5', '6']
|
\w |
文字と数字 日本語を含む
re.findall('\w', 'あい12cd56\n')
→['あ', 'い', '1', '2', 'c', 'd', '5', '6']
|
\W |
文字と数字以外 日本語を含む
re.findall('\W','あい12cd56\n')
→['\n']
|
. |
任意の1文字
re.findall('a.b','abc aQb.')
→['aQb']
|
* |
0回以上の繰り返し
re.findall('ab*', 'a ab abbb aQb.' )
→['a', 'ab', 'abbb', 'a']
0回以上の繰り返しとは言語明瞭意味不明です。
*が作用するのは直前の文字bです。
0回の繰り返しとは、bが0回になるので、aで一致することになります。aとaQbが一致します。
abはbが1回一致です。abbbはbが3回一致です。
|
+ |
1回以上の繰り返し
re.indall('ab+', 'a ab abbb aQb.')
→['ab', 'abbb']
*と違うのは0回を含まないことです。よってaとaQbは一致しません。
|
? |
0回または1回
re.re.findall('https?','http https httpz httpss')
→['http', 'https', 'http', 'https']
?の対象文字はsです。0回一致はhttpです。1回一致はhttpsです。
|
\A
|
文字列の先頭
re.findall('\Aab.', 'abc ab1 ab2')
→['abc'] 文字列の先頭
abcが一致しています。
|
\Z |
文字列の末尾
re.findall('ab.\Z', 'abc ab1 ab2')
→['ab2']
文字列の末尾ab2が一致しています。
|
{m}
|
m回の繰り返し
re.findall('o{2}', 'god google')
→['oo']
oが2文字のごおgoogleで一致しています。
|
{m,n}
|
m〜n回の繰り返し
re.re.findall('e{2,3}','get feel greeen')
→['ee', 'eee']
|
[] |
集合、範囲
re.findall('[2-4]', '1 2book 4note 5pen')
→['2', '4'] 数字の2から4までを指定します。2と4が一致しました。
|
() |
グループ化
re.search('a(bc)+','abcbc')
→<re.Match object; span=(0, 5), match='abcbc'> bcのグループが2回一致しています。
+や?などをつけないとあまり出番がないようです。
new_text = re.search('a(bc)','abcbc')
→
<re.Match object; span=(0, 3), match='abc'>
new_text = re.search('abc','abcbc') <re.Match object;
span=(0, 3), match='abc'> 結果が同じです。
|
| |
または (C言語の|と同じ)
re.findall('ap|th','apple think')
→['ap', 'th'] apとthが一致しています。
|
.
貪欲マッチと非貪欲マッチ
言葉で説明するよりソースと結果を見たほうが分かりやすいです。
#普通に数字だけマッチ
new_text = re.search('\d','abc,12345')
print(new_text)
<re.Match object; span=(4, 5), match='1'>
#数字の前の任意の位置文字にもマッチ
new_text = re.search('.\d','abc,12345')
print(new_text)
<re.Match object; span=(3, 5), match=',1'>
#貪欲マッチ
new_text = re.search('.*\d','abc,12345')
print(new_text)
<re.Match object; span=(0, 9), match='abc,12345'>
new_text = re.search('\d.*','abc,12345')
print(new_text)
<re.Match object; span=(4, 9), match='12345'>
#非貪欲マッチ
new_text = re.search('.*?\d','abc,12345')
print(new_text)
<re.Match object; span=(0, 5), match='abc,1'>
new_text = re.search('\d.*?','abc,12345')
print(new_text)
<re.Match object; span=(4, 5), match='1'>
貪欲マッチ .*非貪欲マッチ .*?先頭につけるか、末尾につけるかで結果がかわります。なんか分かりにくいですが、 .*
この2文字で貪欲マッチの意味をなし、 ?を付加すると否定となります。
group()の使い方
グループ化したデータがマッチしたときgroup(x)で要素を取り出せます。
new_text = re.search('(\d{3})-(\d{4})-(\d{4})', '090-1234-5678')
print(new_text)
<re.Match object; span=(0, 13), match='090-1234-5678'>
print (new_text.lastindex)
3
print(new_text.group())
090-1234-5678
print(new_text.group(0))
090-1234-5678
print(new_text.group(1))
090
print(new_text.group(2))
1234
print(new_text.group(3))
5678
-で区切られた携帯電話番号において、マッチした文字が1から3までのインデックスで取得できます。インデックスの最大数はlastindexで与えられます。
フラグ引数
フラグ引数を使うことによってマッチする条件をコントロールできます。 1.大文字と小文字を区別しない(re.IGNORECASE)
正規表現は基本的に大文字小文字を区別しています。区別したくないときはre.IGNORECASE をセットします。
org_text = r"Hello pySerial. I love pyGame."
res = re.findall('Py', org_text)
Pyではヒットしません。
org_text = r"Hello pySerial. I love pyGame."
res = re.findall('Py', org_text, re.IGNORECASE)
結果:
['py', 'py']
複数行の行頭・行末でのマッチ(re.MULTILINE )
複数行の行頭にある小文字のアルファベットが重要なデータで、これを抽出します。
org_text = r"""abc 789 ssd
hello 456 pySerial
love pyGame.256"
"""
res = re.findall('^[a-z]+', org_text, re.MULTILINE)
結果:
['abc', 'hello', 'love']
re.MULTILINEがないとabcだけマッチします。行末でマッチさせるには、
res = re.findall('[a-z]+$', org_text, re.MULTILINE)
$を付けます。
|