文字にマッチするもの
一覧
文字 | それぞれの文字にマッチする。Python3ではUnicode文字も対象。 |
. |
'\n' 以外の任意の一文字にマッチする。re.S /re.DOTALL フラグが設定されると’\n’にもマッチする。 |
[...] |
文字クラス。[] 内に含まれる文字のいずれか一文字マッチする。'-' で範囲指定も可能。たとえば[abc] はa 、b 、c にマッチ。[a-z] は全ての小文字のアルファベット文字にマッチ。[abcx-z] はa 、b 、c 、x 、y 、z にマッチ。Unicode文字にも対応していて[0-9] は全角の数字にマッチ。先頭に'^' 記号があると、その文字クラス以外の文字列がマッチする。たとえば[^abc] はa 、b 、c 以外にマッチする。 |
\d |
数字[0-9]にマッチ。Unicode文字の数字も対象となり、全角の数字[0-9] なども対象となる。re.A /re.ASCII フラグが設定されると[0-9]にのみマッチする。バイト列に対しては[0-9] と等価。 |
\D |
数字以外の文字にマッチ。Unicode文字の数字も除外対象となる。 |
\w |
任意のUnicode単語文字にマッチ。あらゆる単語の一部になりうる文字で、文字・数字・アンダースコアが含まれる。re.ASCIIフラグが設定された場合[a-zA-Z0-9_] にマッチ。バイト列に対しては[a-zA-Z0-9_]と等価。 |
\W |
Unicode単語文字以外の文字にマッチ。 |
\s |
任意の空白文字とマッチ。[ \t\n\r\f\v] など。 |
\S |
空白以外の文字にマッチ。 |
Pythonの標準エスケープも正規表現で認識される。
\a
、\b
、\f
、\n
、\r
、\t
、\u
、\U
、\
v、\x
、\\
ただし\b
は単語境界を表し、文字クラス内でのみバックスペース文字を表す。
文字クラス
文字クラスはUnicode文字にも対応。
1 2 3 4 5 |
import re print(re.findall(r'[あ-ん]', "我考える故に我あり")) print(re.findall(r'[^あ-ん]', "我考える故に我あり")) # ['え', 'る', 'に', 'あ', 'り'] # ['我', '考', '故', '我'] |
文字クラス内では特殊文字は意味を失い、1つの文字として扱われる。たとえば[(*+)]
は'('
、'*'
、'+'
、')'
のいずれかとマッチする。
1 2 3 |
import re print(re.findall(r'[(*+?)]', "(1+2)*3=9?")) # ['(', '+', ')', '*', '?'] |
'^'
と、']'
は例外で、'^'
は先頭の場合のみ否定の意味でそれ以外の位置では文字'^'
を表し、']'
は末尾では無視されそれ以外の位置では文字']'
を表す。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import re s = "array[n]=var^2" print(re.findall(r'[^a]',s)) # ['r', 'r', 'y', '[', 'n', ']', '=', 'v', 'r', '^', '2'] print(re.findall(r'[a^]',s)) # ['a', 'a', 'a', '^'] print(re.findall(r'[[]',s)) # ['['] print(re.findall(r'[[a]',s)) # ['a', 'a', '[', 'a'] print(re.findall(r'[]]',s)) # [']'] print(re.findall(r'[a]]',s)) # [] print(re.findall(r'[]a]',s)) # ['a', 'a', ']', 'a'] |
位置にマッチするもの
一覧
^ |
文字列の先頭にマッチする。たとえば'^A' は先頭の文字が'A' であることを示す。デフォルトでは文字列全体の先頭だけにマッチするが、re.MULTILINE が指定されていれば、各改行の前にもマッチする。 |
$ |
文字列の末尾にマッチする。たとえば’Z$' は末尾の文字が'Z' であることを示す。デフォルトでは文字列全体の末尾だけにマッチするが、re.MULTILINE が指定されていれば、各改行の後にもマッチする。 |
\b | 単語境界にマッチする。単語境界は[^a-zA-Z0-9] 。 |
MULTILINE
re.MULTILINE
フラグ指定の有無による動作の違いを確認する。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
import re s1 = "Some people feel the rain.\nOthers just get wet." s2 = """Love the life you live. Live the life you love.""" print(re.findall(r'^.+', s1)) print(re.findall(r'.+$', s1)) # ['Some people feel the rain.'] # ['Others just get wet.'] print(re.findall(r'^.+', s2)) print(re.findall(r'.+$', s2)) # ['Love the life you live.'] # ['Live the life you love.'] print(re.findall(r'^.+', s1, flags=re.MULTILINE)) print(re.findall(r'.+$', s1, flags=re.MULTILINE)) # ['Some people feel the rain.', 'Others just get wet.'] # ['Some people feel the rain.', 'Others just get wet.'] print(re.findall(r'^.+', s2, flags=re.MULTILINE)) print(re.findall(r'.+$', s2, flags=re.MULTILINE)) # ['Love the life you live.', 'Live the life you love.'] # ['Love the life you live.', 'Live the life you love.'] |
\b – 文字列境界
文字列境界が[^a-zA-Z0-9]
であることが、以下の例で分かる。
1 2 3 4 5 6 7 |
import re [print(match) for match in re.finditer(r'\bab\b', "ab_ab0ab ab-ab,ab;ab(ab)")] # <_sre.SRE_Match object; span=(9, 11), match='ab'> # <_sre.SRE_Match object; span=(12, 14), match='ab'> # <_sre.SRE_Match object; span=(15, 17), match='ab'> # <_sre.SRE_Match object; span=(18, 20), match='ab'> #<_sre.SRE_Match object; span=(21, 23), match='ab'> |
繰り返し
* |
直前の文字の0回以上でできるだけ多くの繰り返し。'ab*' はabbc に対してa やab ではなくabb としてマッチする。 |
+ |
直前の文字の1回以上でできるだけ多くの繰り返し。'ab+' はabbbc に対してab やabb ではなくabbb としてマッチする。'ab?' はabb... に対してab としてマッチする。 |
? |
直前の文字が0個か1個でできるだけ多くの場合にマッチ。 |
{m} |
直前の文字のm 回の繰り返し。 |
{m,n} |
直前の文字のm 回以上n 回以下でできるだけ多くの繰り返し。 |
{m,} |
直前の文字のm 回以上でできるだけ多くの繰り返し。 |
{,n} |
直前の文字のn回以下でできるだけ多くの繰り返し。 |
実行例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
import re print(re.findall(r'a*', "a aa aaa")) # ['a', '', 'aa', '', 'aaa', ''] print(re.findall(r'a+', "a aa aaa")) # ['a', 'aa', 'aaa'] print(re.findall(r'aa?', "a aa aaa")) # ['a', 'aa', 'aa', 'a'] print(re.findall(r'a{2}', "a aa aaa aaaa")) # ['aa', 'aa', 'aa', 'aa'] print(re.findall(r'a{2,3}', "a aa aaa aaaa")) # ['aa', 'aaa', 'aaa'] print(re.findall(r'a{2,}', "a aa aaa aaaa")) # ['aa', 'aaa', 'aaaa'] print(re.findall(r'a{,3}', "a aa aaa aaaa")) # ['a', '', 'aa', '', 'aaa', '', 'aaa', 'a', ''] |
'a*'
は長さ0の文字列にもマッチする。マッチした文字列の直後の空文字列にマッチすることが、以下の例でもわかる。
1 2 |
print(re.findall(r'c*', "abbcccdddd")) # ['', '', '', 'ccc', '', '', '', '', ''] |
'aa?'
はa
とaa
にマッチするが、最後のaaa
に対しては、先頭のaa
にマッチした後、残ったa
にマッチしている。
'a{2}'
は先頭からaa
にマッチしていき、最後のaaaa
には2回マッチしている。
'a{,3}'
は各マッチの後の長さ0の文字列にもマッチしていて、最後のaaaa
に対しては先頭のaaa
にマッチした後、残ったa
にマッチしている。
選択演算子(|)
'|'
で区切られた要素のどれかとマッチすればよいことを表す。
1 2 3 4 |
import re print(re.findall(r"bi|di", r"bibbidi bobbidi boo")) # ['bi', 'bi', 'di', 'bi', 'di'] |
注意点としては、'|'
で区切られた要素の左から右へマッチング評価され、ある要素がマッチしたと評価されると、その部分列に対してそれ以降の要素の評価は行われない。
1 2 3 4 5 6 7 8 |
import re print(re.findall(r"aa|aaaa", r"a,aa,aaa,aaaa")) # ['aa', 'aa', 'aa', 'aa'] # 先に'aa'で評価されると'aaaa'で評価されない print(re.findall(r"aaaa|aa", r"a,aa,aaa,aaaa")) # ['aa', 'aa', 'aaaa'] |
グループ(…)
()
で囲んだ要素はグループ化されて、1つの文字と同じ様に扱われる。たとえば次の例では、'Aa'
というパターンを1つのグループとして、それが繰り返される回数でマッチングさせている。
1 2 3 4 5 6 7 8 9 10 |
import re def match_list(ptn, s, flags=0): return [a.group() for a in re.finditer(ptn, s, flags)] print(match_list(r"(Aa)+", r"Aa-AaAa-AaAaAa")) print(match_list(r"(Aa){2}", r"Aa-AaAa-AaAaAa")) # ['Aa', 'AaAa', 'AaAaAa'] # ['AaAa', 'AaAa'] |
後方参照
()
囲った部分には、先頭から順番に番号nがふられて、そのあとで'\n'
のようにマッチした内容を再利用できる。
1 2 3 4 5 |
import re print(re.search(r'\d{3}-(\d{4})-\1', "090-1234-5678")) # None print(re.search(r'\d{3}-(\d{4})-\1', "090-1234-1234")) # <_sre.SRE_Match object; span=(0, 13), match='090-1234-1234'> |