re --- 正規表現操作

ソースコード: Lib/re/


このモジュールは Perl に見られる正規表現マッチング操作と同様のものを提供します。

Both patterns and strings to be searched can be Unicode strings (str) as well as 8-bit strings (bytes). However, Unicode strings and 8-bit strings cannot be mixed: that is, you cannot match a Unicode string with a bytes pattern or vice-versa; similarly, when asking for a substitution, the replacement string must be of the same type as both the pattern and the search string.

正規表現では、特殊な形式を表すためや、特殊文字をその特殊な意味を発動させず使うために、バックスラッシュ文字 ('\') を使います。こうしたバックスラッシュの使い方は、 Python の文字列リテラルにおける同じ文字の使い方と衝突します。例えば、リテラルのバックスラッシュにマッチさせるには、パターン文字列として '\\\\' と書かなければなりません。なぜなら、正規表現は \\ でなければならないうえ、それぞれのバックスラッシュは標準の Python 文字列リテラルで \\ と表現せねばならないからです。 Python の文字列リテラルにおいて、バックスラッシュの使用による不正なエスケープ文字がある場合は、SyntaxWarning が発生し、将来的には SyntaxError になることにも注意してください。この動作は、正規表現として有効な文字列に対しても同様です。

これを解決するには、正規表現パターンに Python の raw 文字列記法を使います。 'r' を前置した文字列リテラル内ではバックスラッシュが特別扱いされません。従って "\n" が改行一文字からなる文字列であるのに対して、 r"\n"'\''n' の二文字からなる文字列です。通常、 Python コード中では、パターンをこの raw 文字列記法を使って表現します。

重要なこととして、大抵の正規表現操作は、モジュールレベルの関数としても、 コンパイル済み正規表現 のメソッドとしても利用できます。関数は正規表現オブジェクトを前もってコンパイルする必要がない近道ですが、微調整のための変数が減ります。

参考

サードパーティの regex モジュールは、標準ライブラリの re モジュールと互換な API を持ちながら、追加の機能とより徹底した Unicode サポートを提供します。

正規表現のシンタックス

正規表現 (または RE) は、その表現にマッチ (match) する文字列の集合を指定します。このモジュールの関数を使えば、ある文字列が与えられた正規表現にマッチするか (または、与えられた正規表現がある文字列にマッチするか、と言い換えても同じことになります) を検査できます。

正規表現を連結することで新しい正規表現を作れます。AB がともに正規表現であれば AB も正規表現です。一般的に、ある文字列 pA にマッチし、別の文字列 qB にマッチするなら、文字列 pq は AB にマッチします。ただし、 A または B に優先度の低い演算が含まれる場合や、 AB との間に境界条件がある場合や、番号付けされたグループ参照をしている場合、を除きます。こうして、ここで述べるような簡単な基本表現から、複雑な表現を容易に構築できます。正規表現に関する理論と実装の詳細については Friedl 本 [Frie09] か、コンパイラの構築に関するテキストを参照してください。

以下で正規表現の形式を簡単に説明します。詳細な情報ややさしい説明は、 正規表現 HOWTO を参照してください。

正規表現には、特殊文字と通常文字の両方を含められます。 'A''a' 、または '0' のようなほとんどの通常文字は、最も単純な正規表現です。これは単純に、その文字自体にマッチします。通常文字は連結できるので、 last は文字列 'last' にマッチします。 (この節では以降、正規表現は一般にクオートを使わず この特殊スタイルで 表記し、マッチ対象の文字列は、 'シングルクオートで括って' 表記します。)

'|''(' といったいくつかの文字は特殊です。特殊文字は通常文字の種別を表したり、周辺の通常文字に対する解釈方法に影響します。

繰り返しの演算子または修飾子 (*+?{m,n} など) は直接入れ子にはできません。これは、非貪欲な修飾子の接尾辞 ? や他の実装での他の修飾子との曖昧さを回避します。内側で繰り返したものをさらに繰り返すには、丸括弧が使えます。例えば、正規表現 (?:a{6})* は 6 の倍数個の 'a' 文字にマッチします。

特殊文字を以下に示します:

.

(ドット) デフォルトのモードでは改行以外の任意の文字にマッチします。 DOTALL フラグが指定されていれば改行も含む全ての文字にマッチします。

^

(キャレット) 文字列の先頭にマッチし、 MULTILINE モードでは各改行の直後にもマッチします。

$

文字列の末尾、あるいは文字列の末尾の改行の直前にマッチし、 MULTILINE モードでは改行の前にもマッチします。 foo は 'foo' と 'foobar' の両方にマッチしますが、正規表現 foo$ は 'foo' だけにマッチします。興味深いことに、 'foo1\nfoo2\n'foo.$ で検索した場合、通常は 'foo2' だけにマッチしますが、 MULTILINE モードでは 'foo1' にもマッチします。 $ だけで 'foo\n' を検索した場合、2 つの (空の) マッチを見つけます: 1つは改行の直前で、もう1つは文字列の末尾です。

*

直前の正規表現を 0 回以上、できるだけ多く繰り返したものにマッチさせる結果の正規表現にします。例えば ab* は 'a'、'ab'、または 'a' に任意個数の 'b' を続けたものにマッチします。

+

直前の正規表現を 1 回以上繰り返したものにマッチさせる結果の正規表現にします。例えば ab+ は 'a' に 1 つ以上の 'b' が続いたものにマッチし、単なる 'a' にはマッチしません。

?

直前の正規表現を 0 回か 1 回繰り返したものにマッチさせる結果の正規表現にします。例えば ab? は 'a' あるいは 'ab' にマッチします。

*?, +?, ??

'*''+' 、および '?' 修飾子は全て 貪欲 (greedy) マッチで、できるだけ多くのテキストにマッチします。この挙動が望ましくない時もあります。例えば正規表現 <.*>'<a> b <c>' に対してマッチされると、 '<a>' だけでなく文字列全体にマッチしてしまいます。修飾子の後に ? を追加すると、 非貪欲 (non-greedy) あるいは 最小 (minimal) のマッチが行われ、できるだけ 少ない 文字にマッチします。正規表現 <.*?> を使うと '<a>' だけにマッチします。

*+, ++, ?+

Like the '*', '+', and '?' quantifiers, those where '+' is appended also match as many times as possible. However, unlike the true greedy quantifiers, these do not allow back-tracking when the expression following it fails to match. These are known as possessive quantifiers. For example, a*a will match 'aaaa' because the a* will match all 4 'a's, but, when the final 'a' is encountered, the expression is backtracked so that in the end the a* ends up matching 3 'a's total, and the fourth 'a' is matched by the final 'a'. However, when a*+a is used to match 'aaaa', the a*+ will match all 4 'a', but when the final 'a' fails to find any more characters to match, the expression cannot be backtracked and will thus fail to match. x*+, x++ and x?+ are equivalent to (?>x*), (?>x+) and (?>x?) correspondingly.

バージョン 3.11 で追加.

{m}

直前の正規表現をちょうど m 回繰り返したものにマッチさせるよう指定します。それより少ないマッチでは正規表現全体がマッチしません。例えば、 a{6} は 6 個ちょうどの 'a' 文字にマッチしますが、 5 個ではマッチしません。

{m,n}

直前の正規表現を m 回から n 回、できるだけ多く繰り返したものにマッチさせる結果の正規表現にします。例えば、a{3,5} は、3 個から 5 個の 'a' 文字にマッチします。m を省略すると下限は 0 に指定され、n を省略すると上限は無限に指定されます。例として、 a{4,}b'aaaab' や、1,000 個の 'a' 文字に 'b' が続いたものにマッチしますが、'aaab' にはマッチしません。コンマは省略できません、省略すると修飾子が上で述べた形式と混同されてしまうからです。

{m,n}?

結果の正規表現は、前にある正規表現を、m 回から n 回まで繰り返したものにマッチし、できるだけ 少なく 繰り返したものにマッチするようにします。これは、前の数量詞の非貪欲版です。例えば、 6 文字文字列 'aaaaaa' では、 a{3,5} は、5 個の 'a' 文字にマッチしますが、 a{3,5}? は 3 個の文字にマッチするだけです。

{m,n}+

Causes the resulting RE to match from m to n repetitions of the preceding RE, attempting to match as many repetitions as possible without establishing any backtracking points. This is the possessive version of the quantifier above. For example, on the 6-character string 'aaaaaa', a{3,5}+aa attempt to match 5 'a' characters, then, requiring 2 more 'a's, will need more characters than available and thus fail, while a{3,5}aa will match with a{3,5} capturing 5, then 4 'a's by backtracking and then the final 2 'a's are matched by the final aa in the pattern. x{m,n}+ is equivalent to (?>x{m,n}).

バージョン 3.11 で追加.

\

特殊文字をエスケープ ( '*''?' などの文字にマッチできるようにする) し、または特殊シーケンスを合図します。特殊シーケンスは後で議論します。

パターンを表現するのに raw 文字列を使っていないのであれば、 Python ももまた、バックスラッシュを文字列リテラルでエスケープシーケンスとして使うことを思い出して下さい。そのエスケープシーケンスを Python のパーザが認識しないなら、そのバックスラッシュとそれに続く文字が結果の文字列に含まれます。しかし、Python が結果のシーケンスを認識するなら、そのバックスラッシュは 2 回繰り返さなければいけません。これは複雑で理解しにくいので、ごく単純な表現以外は、全て raw 文字列を使うことを強く推奨します。

[]

文字の集合を指定するのに使います。集合の中では:

  • 文字を個別に指定できます。 [amk]'a''m' または 'k' にマッチします。

  • 連続した文字の範囲を、 '-' を2 つの文字で挟んで指定できます。例えば、 [a-z] はあらゆる小文字の ASCII 文字にマッチします。[0-5][0-9]00 から 59 まで全ての 2 桁の数字にマッチします。[0-9A-Fa-f] は任意の 16 進数字にマッチします。- がエスケープされているか (例: [a\-z])、先頭や末尾の文字にされていると (例: [-a][a-])、リテラル '-' にマッチします。

  • 集合の中では、特殊文字はその特殊な意味を失います。例えば [(+*)] はリテラル文字 '(''+''*' 、または ')' のどれにでもマッチします。

  • Character classes such as \w or \S (defined below) are also accepted inside a set, although the characters they match depend on the flags used.

  • 補集合 をとって範囲内にない文字にマッチできます。集合の最初の文字が '^' なら、集合に 含まれない 全ての文字にマッチします。例えば、 [^5]'5' を除くあらゆる文字にマッチし、 [^^]'^' を除くあらゆる文字にマッチします。 ^ は集合の最初の文字でなければ特別の意味を持ちません。

  • To match a literal ']' inside a set, precede it with a backslash, or place it at the beginning of the set. For example, both [()[\]{}] and []()[{}] will match a right bracket, as well as left bracket, braces, and parentheses.

  • Unicode Technical Standard #18 にあるような集合の入れ子や集合操作が将来追加される可能性があります。これは構文を変化させるもので、この変化を容易にするために、さしあたって曖昧な事例には FutureWarning が送出されます。これはリテラル '[' で始まる集合や、リテラル文字の連続 '--''&&''~~' および '||' を含む集合を含みます。警告を避けるにはバックスラッシュでエスケープしてください。

バージョン 3.7 で変更: 文字セットが将来意味論的に変化する構造を含むなら FutureWarning が送出されます。

|

AB を任意の正規表現として、 A|BAB のいずれかにマッチする正規表現を作成します。この方法で任意の数の正規表現を '|' で分離できます。これはグループ (下記参照) 中でも使えます。対象文字列を走査するとき、'|' で分離された正規表現は左から右へ順に試されます。一つのパターンが完全にマッチしたとき、そのパターン枝が受理されます。つまり、ひとたび A がマッチしてしまえば、例え B によって全体のマッチが長くなるとしても、 B はもはや走査されません。言いかえると、 '|' 演算子は決して貪欲にはなりません。リテラル '|' にマッチするには、 \| を使うか、 [|] のように文字クラス中に囲みます。

(...)

丸括弧で囲まれた正規表現にマッチするとともに、グループの開始と終了を表します。グループの中身は以下で述べるように、マッチが実行された後で回収したり、その文字列中で以降 \number 特殊シーケンスでマッチしたりできます。リテラル '('')' にマッチするには、\(\) を使うか、文字クラス中に囲みます: [(][)]

(?...)

これは拡張記法です ('(' に続く '?' はそれ以上の意味を持ちません) 。 '?' に続く最初の文字がこの構造の意味と特有の構文を決定します。拡張は一般に新しいグループを作成しません。ただし (?P<name>...) はこの法則の唯一の例外です。現在サポートされている拡張は以下の通りです。

(?aiLmsux)

(One or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x'.) The group matches the empty string; the letters set the corresponding flags for the entire regular expression:

  • re.A (ASCII-only matching)

  • re.I (ignore case)

  • re.L (locale dependent)

  • re.M (multi-line)

  • re.S (dot matches all)

  • re.U (Unicode matching)

  • re.X (verbose)

(The flags are described in モジュールコンテンツ.) This is useful if you wish to include the flags as part of the regular expression, instead of passing a flag argument to the re.compile() function. Flags should be used first in the expression string.

バージョン 3.11 で変更: This construction can only be used at the start of the expression.

(?:...)

普通の丸括弧の、キャプチャしない版です。丸括弧で囲まれた正規表現にマッチしますが、このグループがマッチした部分文字列は、マッチを実行したあとで回収することも、そのパターン中で以降参照することも できません

(?aiLmsux-imsx:...)

(Zero or more letters from the set 'a', 'i', 'L', 'm', 's', 'u', 'x', optionally followed by '-' followed by one or more letters from the 'i', 'm', 's', 'x'.) The letters set or remove the corresponding flags for the part of the expression:

  • re.A (ASCII-only matching)

  • re.I (ignore case)

  • re.L (locale dependent)

  • re.M (multi-line)

  • re.S (dot matches all)

  • re.U (Unicode matching)

  • re.X (verbose)

(The flags are described in モジュールコンテンツ.)

The letters 'a', 'L' and 'u' are mutually exclusive when used as inline flags, so they can't be combined or follow '-'. Instead, when one of them appears in an inline group, it overrides the matching mode in the enclosing group. In Unicode patterns (?a:...) switches to ASCII-only matching, and (?u:...) switches to Unicode matching (default). In bytes patterns (?L:...) switches to locale dependent matching, and (?a:...) switches to ASCII-only matching (default). This override is only in effect for the narrow inline group, and the original matching mode is restored outside of the group.

バージョン 3.6 で追加.

バージョン 3.7 で変更: 文字 'a''L' および 'u' もグループ中で使えます。

(?>...)

Attempts to match ... as if it was a separate regular expression, and if successful, continues to match the rest of the pattern following it. If the subsequent pattern fails to match, the stack can only be unwound to a point before the (?>...) because once exited, the expression, known as an atomic group, has thrown away all stack points within itself. Thus, (?>.*). would never match anything because first the .* would match all characters possible, then, having nothing left to match, the final . would fail to match. Since there are no stack points saved in the Atomic Group, and there is no stack point before it, the entire expression would thus fail to match.

バージョン 3.11 で追加.

(?P<name>...)

Similar to regular parentheses, but the substring matched by the group is accessible via the symbolic group name name. Group names must be valid Python identifiers, and in bytes patterns they can only contain bytes in the ASCII range. Each group name must be defined only once within a regular expression. A symbolic group is also a numbered group, just as if the group were not named.

名前付きグループは 3 つのコンテキストで参照できます。パターンが (?P<quote>['\"]).*?(?P=quote) (シングルまたはダブルクオートで囲まれた文字列にマッチ) ならば:

グループ "quote" を参照するコンテキスト

参照する方法

その同じパターン中

  • (?P=quote) (示したとおり)

  • \1

マッチオブジェクト m の処理時

  • m.group('quote')

  • m.end('quote') (など)

re.sub()repl 引数へ渡される文字列中

  • \g<quote>

  • \g<1>

  • \1

バージョン 3.12 で変更: In bytes patterns, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

(?P=name)

名前付きグループへの後方参照です。これは name という名前の既出のグループがマッチした文字列にマッチします。

(?#...)

コメントです。括弧の中身は単純に無視されます。

(?=...)

... が次に続くものにマッチすればマッチしますが、文字列をまったく消費しません。これは 先読みアサーション (lookahead assertion) と呼ばれます。例えば、Isaac (?=Asimov)'Isaac ' に、その後に 'Asimov' が続く場合にのみ、マッチします。

(?!...)

... が次に続くものにマッチしなければマッチします。これは 否定先読みアサーション (negative lookahead assertion) です。例えば、Isaac (?!Asimov)'Isaac ' に、その後に 'Asimov' が続か ない 場合にのみ、マッチします。

(?<=...)

その文字列における現在位置の前に、現在位置で終わる ... とのマッチがあれば、マッチします。これは 後読みアサーション と呼ばれます。(?<=abc)def は、後読みは 3 文字をバックアップし、含まれているパターンがマッチするか検査するので 'abcdef' にマッチを見つけます。含まれるパターンは、固定長の文字列にのみマッチしなければなりません。すなわち、 abca|b は許されますが、a*a{3,4} は許されません。肯定後読みアサーションで始まるパターンは、検索される文字列の先頭とは決してマッチしないことに注意して下さい。match() 関数ではなく search() 関数を使う方が望ましいでしょう:

>>> import re
>>> m = re.search('(?<=abc)def', 'abcdef')
>>> m.group(0)
'def'

この例ではハイフンに続く単語を探します:

>>> m = re.search(r'(?<=-)\w+', 'spam-egg')
>>> m.group(0)
'egg'

バージョン 3.5 で変更: 固定長のグループ参照をサポートするようになりました。

(?<!...)

その文字列における現在位置の前に ... とのマッチがなければ、マッチします。これは 否定後読みアサーション(negative lookbehind assertion) と呼ばれます。肯定後読みアサーションと同様に、含まれるパターンは固定長の文字列にのみマッチしなければなりません。否定後読みアサーションで始まるパターンは検索される文字列の先頭でマッチできます。

(?(id/name)yes-pattern|no-pattern)

与えられた idname のグループが存在すれば yes-pattern との、存在しなければ no-pattern とのマッチを試みます。no-pattern はオプションであり省略できます。例えば、(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$) は貧弱な E-mail マッチングパターンで、'<user@host.com>''user@host.com' にはマッチしますが、'<user@host.com''user@host.com>' にはマッチしません。

バージョン 3.12 で変更: Group id can only contain ASCII digits. In bytes patterns, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

特殊シーケンスは '\' と以下のリストの文字から構成されます。通常文字が ASCII 数字でも ASCII 文字でもなければ、結果の正規表現は 2 番目の文字にマッチします。例えば、\$ は文字 '$' にマッチします。

\number

同じ番号のグループの中身にマッチします。グループは 1 から始まる番号をつけられます。例えば、 (.+) \1 は、 'the the' あるいは '55 55' にマッチしますが、 'thethe' にはマッチしません(グループの後のスペースに注意して下さい)。この特殊シーケンスは最初の 99 グループのうちの一つとのマッチにのみ使えます。 number の最初の桁が 0 であるか、 number が 3 桁の 8 進数であれば、それはグループのマッチとしてではなく、 8 進値 number を持つ文字として解釈されます。文字クラスの '['']' の間では全ての数値エスケープが文字として扱われます。

\A

文字列の先頭でのみマッチします。

\b

Matches the empty string, but only at the beginning or end of a word. A word is defined as a sequence of word characters. Note that formally, \b is defined as the boundary between a \w and a \W character (or vice versa), or between \w and the beginning or end of the string. This means that r'\bat\b' matches 'at', 'at.', '(at)', and 'as at ay' but not 'attempt' or 'atlas'.

The default word characters in Unicode (str) patterns are Unicode alphanumerics and the underscore, but this can be changed by using the ASCII flag. Word boundaries are determined by the current locale if the LOCALE flag is used.

注釈

Inside a character range, \b represents the backspace character, for compatibility with Python's string literals.

\B

Matches the empty string, but only when it is not at the beginning or end of a word. This means that r'at\B' matches 'athens', 'atom', 'attorney', but not 'at', 'at.', or 'at!'. \B is the opposite of \b, so word characters in Unicode (str) patterns are Unicode alphanumerics or the underscore, although this can be changed by using the ASCII flag. Word boundaries are determined by the current locale if the LOCALE flag is used.

\d
Unicode (str) パターンでは:

Matches any Unicode decimal digit (that is, any character in Unicode character category [Nd]). This includes [0-9], and also many other digit characters.

Matches [0-9] if the ASCII flag is used.

8 ビット (bytes) パターンでは:

Matches any decimal digit in the ASCII character set; this is equivalent to [0-9].

\D

Matches any character which is not a decimal digit. This is the opposite of \d.

Matches [^0-9] if the ASCII flag is used.

\s
Unicode (str) パターンでは:

Matches Unicode whitespace characters (which includes [ \t\n\r\f\v], and also many other characters, for example the non-breaking spaces mandated by typography rules in many languages).

Matches [ \t\n\r\f\v] if the ASCII flag is used.

8 ビット (bytes) パターンでは:

ASCII 文字セットで空白文字と見なされる文字にマッチします。これは [ \t\n\r\f\v] と等価です。

\S

Matches any character which is not a whitespace character. This is the opposite of \s.

Matches [^ \t\n\r\f\v] if the ASCII flag is used.

\w
Unicode (str) パターンでは:

Matches Unicode word characters; this includes all Unicode alphanumeric characters (as defined by str.isalnum()), as well as the underscore (_).

Matches [a-zA-Z0-9_] if the ASCII flag is used.

8 ビット (bytes) パターンでは:

Matches characters considered alphanumeric in the ASCII character set; this is equivalent to [a-zA-Z0-9_]. If the LOCALE flag is used, matches characters considered alphanumeric in the current locale and the underscore.

\W

Matches any character which is not a word character. This is the opposite of \w. By default, matches non-underscore (_) characters for which str.isalnum() returns False.

Matches [^a-zA-Z0-9_] if the ASCII flag is used.

If the LOCALE flag is used, matches characters which are neither alphanumeric in the current locale nor the underscore.

\Z

文字列の末尾でのみマッチします。

Most of the escape sequences supported by Python string literals are also accepted by the regular expression parser:

\a      \b      \f      \n
\N      \r      \t      \u
\U      \v      \x      \\

(\b は単語の境界を表すのに使われ、文字クラス中でのみ "後退 (backspace)" 文字を意味することに注意してください。)

'\u', '\U', and '\N' escape sequences are only recognized in Unicode (str) patterns. In bytes patterns they are errors. Unknown escapes of ASCII letters are reserved for future use and treated as errors.

8 進エスケープは限られた形式でのみ含まれます。その最初の桁が 0 であるか、それが 3 桁の 8 進数であるならば、それは 8 進エスケープと見なされます。そうでなければ、それはグループ参照です。文字列リテラルでは、8 進エスケープは常にたかだか 3 桁長です。

バージョン 3.3 で変更: '\u''\U' エスケープシーケンスが追加されました。

バージョン 3.6 で変更: '\' と ASCII 文字からなる未知のエスケープはエラーになります。

バージョン 3.8 で変更: The '\N{name}' escape sequence has been added. As in string literals, it expands to the named Unicode character (e.g. '\N{EM DASH}').

モジュールコンテンツ

このモジュールはいくつかの関数、定数、例外を定義します。このうちいくつかの関数は、コンパイル済み正規表現がそなえる完全な機能のメソッドを簡易にしたものです。些細なものを除くほとんどのアプリケーションは常にコンパイル済み形式を使います。

Flags

バージョン 3.6 で変更: フラグ定数は、enum.IntFlag のサブクラスである RegexFlag のインスタンスになりました。

class re.RegexFlag

An enum.IntFlag class containing the regex options listed below.

バージョン 3.11 で追加: - added to __all__

re.A
re.ASCII

Make \w, \W, \b, \B, \d, \D, \s and \S perform ASCII-only matching instead of full Unicode matching. This is only meaningful for Unicode (str) patterns, and is ignored for bytes patterns.

Corresponds to the inline flag (?a).

注釈

The U flag still exists for backward compatibility, but is redundant in Python 3 since matches are Unicode by default for str patterns, and Unicode matching isn't allowed for bytes patterns. UNICODE and the inline flag (?u) are similarly redundant.

re.DEBUG

コンパイルした表現に関するデバッグ情報を出力します。

No corresponding inline flag.

re.I
re.IGNORECASE

Perform case-insensitive matching; expressions like [A-Z] will also match lowercase letters. Full Unicode matching (such as Ü matching ü) also works unless the ASCII flag is used to disable non-ASCII matches. The current locale does not change the effect of this flag unless the LOCALE flag is also used.

Corresponds to the inline flag (?i).

Note that when the Unicode patterns [a-z] or [A-Z] are used in combination with the IGNORECASE flag, they will match the 52 ASCII letters and 4 additional non-ASCII letters: 'İ' (U+0130, Latin capital letter I with dot above), 'ı' (U+0131, Latin small letter dotless i), 'ſ' (U+017F, Latin small letter long s) and 'K' (U+212A, Kelvin sign). If the ASCII flag is used, only letters 'a' to 'z' and 'A' to 'Z' are matched.

re.L
re.LOCALE

Make \w, \W, \b, \B and case-insensitive matching dependent on the current locale. This flag can be used only with bytes patterns.

Corresponds to the inline flag (?L).

警告

This flag is discouraged; consider Unicode matching instead. The locale mechanism is very unreliable as it only handles one "culture" at a time and only works with 8-bit locales. Unicode matching is enabled by default for Unicode (str) patterns and it is able to handle different locales and languages.

バージョン 3.6 で変更: LOCALE can be used only with bytes patterns and is not compatible with ASCII.

バージョン 3.7 で変更: Compiled regular expression objects with the LOCALE flag no longer depend on the locale at compile time. Only the locale at matching time affects the result of matching.

re.M
re.MULTILINE

指定されると、パターン文字 '^' は、文字列の先頭および各行の先頭(各改行の直後)とマッチします;そしてパターン文字 '$' は文字列の末尾および各行の末尾 (改行の直前) とマッチします。デフォルトでは、 '^' は、文字列の先頭とだけマッチし、 '$' は、文字列の末尾および文字列の末尾の改行の直前(がもしあれば)とマッチします。

Corresponds to the inline flag (?m).

re.NOFLAG

Indicates no flag being applied, the value is 0. This flag may be used as a default value for a function keyword argument or as a base value that will be conditionally ORed with other flags. Example of use as a default value:

def myfunc(text, flag=re.NOFLAG):
    return re.match(text, flag)

バージョン 3.11 で追加.

re.S
re.DOTALL

特殊文字 '.' を、改行を含む任意の文字と、とにかくマッチさせます;このフラグがなければ、 '.' は、改行 以外の 任意の文字とマッチします。

Corresponds to the inline flag (?s).

re.U
re.UNICODE

In Python 3, Unicode characters are matched by default for str patterns. This flag is therefore redundant with no effect and is only kept for backward compatibility.

See ASCII to restrict matching to ASCII characters instead.

re.X
re.VERBOSE

This flag allows you to write regular expressions that look nicer and are more readable by allowing you to visually separate logical sections of the pattern and add comments. Whitespace within the pattern is ignored, except when in a character class, or when preceded by an unescaped backslash, or within tokens like *?, (?: or (?P<...>. For example, (? : and * ? are not allowed. When a line contains a # that is not in a character class and is not preceded by an unescaped backslash, all characters from the leftmost such # through the end of the line are ignored.

つまり、10 進数字にマッチする下記のふたつの正規表現オブジェクトは、機能的に等価です:

a = re.compile(r"""\d +  # the integral part
                   \.    # the decimal point
                   \d *  # some fractional digits""", re.X)
b = re.compile(r"\d+\.\d*")

インラインフラグの (?x) に相当します。

関数

re.compile(pattern, flags=0)

正規表現パターンを 正規表現オブジェクト にコンパイルし、以下に述べる match()search() その他のメソッドを使ってマッチングに使えるようにします。

The expression's behaviour can be modified by specifying a flags value. Values can be any of the flags variables, combined using bitwise OR (the | operator).

シーケンス

prog = re.compile(pattern)
result = prog.match(string)

は、以下と同等です

result = re.match(pattern, string)

が、 re.compile() を使い、結果の正規表現オブジェクトを保存して再利用するほうが、一つのプログラムでその表現を何回も使うときに効率的です。

注釈

re.compile() やモジュールレベルのマッチング関数に渡された最新のパターンはコンパイル済みのものがキャッシュされるので、一度に正規表現を少ししか使わないプログラムでは正規表現をコンパイルする必要はありません。

re.search(pattern, string, flags=0)

Scan through string looking for the first location where the regular expression pattern produces a match, and return a corresponding Match. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.

re.match(pattern, string, flags=0)

If zero or more characters at the beginning of string match the regular expression pattern, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

MULTILINE モードにおいても、re.match() は各行の先頭でマッチするのではなく、文字列の先頭でのみマッチすることに注意してください。

string 中のどこででもマッチさせたいなら、代わりに search() を使ってください (search() vs. match() も参照してください)。

re.fullmatch(pattern, string, flags=0)

If the whole string matches the regular expression pattern, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

バージョン 3.4 で追加.

re.split(pattern, string, maxsplit=0, flags=0)

string を、出現した pattern で分割します。 pattern 中でキャプチャの丸括弧が使われていれば、パターン中の全てのグループのテキストも結果のリストの一部として返されます。maxsplit が 0 でなければ、分割は最大 maxsplit 回起こり、残りの文字列はリストの最終要素として返されます。

>>> re.split(r'\W+', 'Words, words, words.')
['Words', 'words', 'words', '']
>>> re.split(r'(\W+)', 'Words, words, words.')
['Words', ', ', 'words', ', ', 'words', '.', '']
>>> re.split(r'\W+', 'Words, words, words.', 1)
['Words', 'words, words.']
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']

セパレータ中にキャプチャグループがあり、それが文字列の先頭にマッチするなら、結果は空文字列で始まります。同じことが文字列の末尾にも言えます。

>>> re.split(r'(\W+)', '...words, words...')
['', '...', 'words', ', ', 'words', '...', '']

そうして、結果のリストにおいて、セパレータの構成要素は常に同じ相対的インデックスに見つかります。

パターンへの空マッチは、直前の空マッチに隣接していないときのみ文字列を分割します。

>>> re.split(r'\b', 'Words, words, words.')
['', 'Words', ', ', 'words', ', ', 'words', '.']
>>> re.split(r'\W*', '...words...')
['', '', 'w', 'o', 'r', 'd', 's', '', '']
>>> re.split(r'(\W*)', '...words...')
['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']

バージョン 3.1 で変更: オプションの flags 引数が追加されました。

バージョン 3.7 で変更: 空文字列にマッチしうるパターンでの分割をサポートするようになりました。

re.findall(pattern, string, flags=0)

Return all non-overlapping matches of pattern in string, as a list of strings or tuples. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result.

The result depends on the number of capturing groups in the pattern. If there are no groups, return a list of strings matching the whole pattern. If there is exactly one group, return a list of strings matching that group. If multiple groups are present, return a list of tuples of strings matching the groups. Non-capturing groups do not affect the form of the result.

>>> re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
>>> re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10')
[('width', '20'), ('height', '10')]

バージョン 3.7 で変更: 空でないマッチが前の空マッチの直後から始められるようになりました。

re.finditer(pattern, string, flags=0)

Return an iterator yielding Match objects over all non-overlapping matches for the RE pattern in string. The string is scanned left-to-right, and matches are returned in the order found. Empty matches are included in the result.

バージョン 3.7 で変更: 空でないマッチが前の空マッチの直後から始められるようになりました。

re.sub(pattern, repl, string, count=0, flags=0)

string 中に出現する最も左の重複しない pattern を置換 repl で置換することで得られる文字列を返します。 パターンが見つからない場合、 string がそのまま返されます。 repl は文字列または関数です。 repl が文字列の場合は、その中の全てのバックスラッシュエスケープが処理されます。 \n は 1 つの改行文字に変換され、 \r はキャリッジリターンに変換される、などです。 ASCII 文字のエスケープで未知のものは将来使うために予約されていて、エラーとして扱われます。 それ以外の \& のような未知のエスケープは残されます。 \6 のような後方参照は、パターンのグループ 6 がマッチした部分文字列で置換されます。 例えば:

>>> re.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')
'static PyObject*\npy_myfunc(void)\n{'

If repl is a function, it is called for every non-overlapping occurrence of pattern. The function takes a single Match argument, and returns the replacement string. For example:

>>> def dashrepl(matchobj):
...     if matchobj.group(0) == '-': return ' '
...     else: return '-'
...
>>> re.sub('-{1,2}', dashrepl, 'pro----gram-files')
'pro--gram files'
>>> re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)
'Baked Beans & Spam'

The pattern may be a string or a Pattern.

オプション引数 count は出現したパターンを置換する最大の回数です。 count は非負整数です。省略されるか 0 なら、出現した全てが置換されます。パターンへの空マッチは前の空マッチに隣接していないときのみ置換されるので、 sub('x*', '-', 'abxd')'-a-b--d-' を返します。

文字列型 repl 引数では、上で述べた文字エスケープや後方参照に加えて、 \g<name>(?P<name>...) 構文で定義された name という名前のグループがマッチした部分文字列を使い、 \g<number> は対応するグループ番号を使います。よって \g<2>\2 と等価ですが、 \g<2>0 のような置換においても曖昧になりません。 \20 は、グループ 20 への参照として解釈され、グループ 2 への参照にリテラル文字 '0' が続いたものとしては解釈されません。後方参照 \g<0> は正規表現とマッチした部分文字列全体で置き換わります。

バージョン 3.1 で変更: オプションの flags 引数が追加されました。

バージョン 3.5 で変更: マッチしなかったグループは空文字列に置き換えられます。

バージョン 3.6 で変更: pattern 中に '\' と ASCII 文字からなる未知のエスケープがあると、エラーになります。

バージョン 3.7 で変更: repl 中に '\' と ASCII 文字からなる未知のエスケープがあると、エラーになります。

バージョン 3.7 で変更: パターンへの空マッチは前の空でないマッチに隣接しているとき置き換えられます。

バージョン 3.12 で変更: Group id can only contain ASCII digits. In bytes replacement strings, group name can only contain bytes in the ASCII range (b'\x00'-b'\x7f').

re.subn(pattern, repl, string, count=0, flags=0)

sub() と同じ操作を行いますが、タプル (new_string、 number_of_subs_made) を返します。

バージョン 3.1 で変更: オプションの flags 引数が追加されました。

バージョン 3.5 で変更: マッチしなかったグループは空文字列に置き換えられます。

re.escape(pattern)

pattern 中の特殊文字をエスケープします。これは正規表現メタ文字を含みうる任意のリテラル文字列にマッチしたい時に便利です。

>>> print(re.escape('https://www.python.org'))
https://www\.python\.org

>>> legal_chars = string.ascii_lowercase + string.digits + "!#$%&'*+-.^_`|~:"
>>> print('[%s]+' % re.escape(legal_chars))
[abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+

>>> operators = ['+', '-', '*', '/', '**']
>>> print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*

この関数は、バックスラッシュのみをエスケープするべき sub() および subn() における置換文字列に使われてはなりません。例えば:

>>> digits_re = r'\d+'
>>> sample = '/usr/sbin/sendmail - 0 errors, 12 warnings'
>>> print(re.sub(digits_re, digits_re.replace('\\', r'\\'), sample))
/usr/sbin/sendmail - \d+ errors, \d+ warnings

バージョン 3.3 で変更: '_' 文字がエスケープされなくなりました。

バージョン 3.7 で変更: 正規表現で特別な意味を持つ文字だけがエスケープされます。結果として、 '!''"''%'"'"',''/'':'';''<''=''>''@'、 と "`" はもはやエスケープされません。

re.purge()

正規表現キャッシュをクリアします。

例外

exception re.error(msg, pattern=None, pos=None)

ここの関数のいずれかに渡された文字列が有効な正規表現ではない (例: 括弧が対になっていない) とき、またはコンパイルやマッチングの際にその他なんらかのエラーが発生した場合に送出される例外です。文字列にパターンとマッチする部分がなくても、それはエラーではありません。エラーインスタンスには、次のような追加の属性があります。

msg

フォーマットされていないエラーメッセージです。

pattern

正規表現のパターンです。

pos

pattern のコンパイルに失敗した場所のインデックスです (None の場合もあります)。

lineno

pos に対応する行です (None の場合もあります)。

colno

pos に対応する列です (None の場合もあります)。

バージョン 3.5 で変更: 追加の属性が追加されました。

正規表現オブジェクト

class re.Pattern

Compiled regular expression object returned by re.compile().

バージョン 3.9 で変更: re.Pattern supports [] to indicate a Unicode (str) or bytes pattern. See ジェネリックエイリアス型.

Pattern.search(string[, pos[, endpos]])

Scan through string looking for the first location where this regular expression produces a match, and return a corresponding Match. Return None if no position in the string matches the pattern; note that this is different from finding a zero-length match at some point in the string.

オプションの第二引数 pos は、文字列のどこから探し始めるかを指定するインデックスで、デフォルトでは 0 です。これは文字列のスライスと完全には同じではありません。パターン文字 '^' は本当の文字列の先頭と改行の直後でマッチしますが、検索を開始するインデックスでマッチするとは限りません。

オプションの引数 endpos は文字列がどこまで検索されるかを制限します。文字列の長さが endpos 文字だったかのようになるので、pos から endpos - 1 の文字に対してだけマッチを探します。endpospos よりも小さいと、マッチは見つかりません。そうでなければ、rx をコンパイル済み正規表現オブジェクトとして、rx.search(string, 0, 50)rx.search(string[:50], 0) と等価です。

>>> pattern = re.compile("d")
>>> pattern.search("dog")     # Match at index 0
<re.Match object; span=(0, 1), match='d'>
>>> pattern.search("dog", 1)  # No match; search doesn't include the "d"
Pattern.match(string[, pos[, endpos]])

If zero or more characters at the beginning of string match this regular expression, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

オプションの pos および endpos 引数は search() メソッドのものと同じ意味です。

>>> pattern = re.compile("o")
>>> pattern.match("dog")      # No match as "o" is not at the start of "dog".
>>> pattern.match("dog", 1)   # Match as "o" is the 2nd character of "dog".
<re.Match object; span=(1, 2), match='o'>

string 中のどこででもマッチさせたいなら、代わりに search() を使ってください (search() vs. match() も参照してください)。

Pattern.fullmatch(string[, pos[, endpos]])

If the whole string matches this regular expression, return a corresponding Match. Return None if the string does not match the pattern; note that this is different from a zero-length match.

オプションの pos および endpos 引数は search() メソッドのものと同じ意味です。

>>> pattern = re.compile("o[gh]")
>>> pattern.fullmatch("dog")      # No match as "o" is not at the start of "dog".
>>> pattern.fullmatch("ogre")     # No match as not the full string matches.
>>> pattern.fullmatch("doggie", 1, 3)   # Matches within given limits.
<re.Match object; span=(1, 3), match='og'>

バージョン 3.4 で追加.

Pattern.split(string, maxsplit=0)

split() 関数にこのコンパイル済みパターンを使うのと同じです。

Pattern.findall(string[, pos[, endpos]])

findall() 関数にこのコンパイル済みパターンを使うのと似ていますが、オプションの pos および endpos 引数で search() のように検索範囲を制限できます。

Pattern.finditer(string[, pos[, endpos]])

finditer() 関数にこのコンパイル済みパターンを使うのと似ていますが、オプションの pos および endpos 引数で search() のように検索範囲を制限できます。

Pattern.sub(repl, string, count=0)

sub() 関数にこのコンパイル済みパターンを使うのと同じです。

Pattern.subn(repl, string, count=0)

subn() 関数にこのコンパイル済みパターンを使うのと同じです。

Pattern.flags

The regex matching flags. This is a combination of the flags given to compile(), any (?...) inline flags in the pattern, and implicit flags such as UNICODE if the pattern is a Unicode string.

Pattern.groups

パターン中のキャプチャグループの数です。

Pattern.groupindex

(?P<id>) で定義されたあらゆるシンボリックグループ名をグループ番号へ写像する辞書です。シンボリックグループがパターン中で全く使われていなければ、この辞書は空です。

Pattern.pattern

パターンオブジェクトがコンパイルされた元のパターン文字列です。

バージョン 3.7 で変更: copy.copy() および copy.deepcopy() をサポートするようになりました。コンパイル済み正規表現オブジェクトはアトミックであると見なされます。

マッチオブジェクト

マッチオブジェクトのブール値は常に True です。 match() および search() はマッチがないとき None を返すので、マッチがあるか単純な if 文で判定できます。

match = re.search(pattern, string)
if match:
    process(match)
class re.Match

Match object returned by successful matches and searches.

バージョン 3.9 で変更: re.Match supports [] to indicate a Unicode (str) or bytes match. See ジェネリックエイリアス型.

Match.expand(template)

Return the string obtained by doing backslash substitution on the template string template, as done by the sub() method. Escapes such as \n are converted to the appropriate characters, and numeric backreferences (\1, \2) and named backreferences (\g<1>, \g<name>) are replaced by the contents of the corresponding group. The backreference \g<0> will be replaced by the entire match.

バージョン 3.5 で変更: マッチしなかったグループは空文字列に置き換えられます。

Match.group([group1, ...])

このマッチの 1 つ以上のサブグループを返します。引数が 1 つなら結果は 1 つの文字列です。複数の引数があれば、結果は引数ごとに 1 項目のタプルです。引数がなければ、 group1 はデフォルトで 0 (マッチ全体が返される) です。 groupN 引数が 0 なら、対応する返り値はマッチした文字列全体です。1 以上 99 以下なら、丸括弧による対応するグループにマッチする文字列です。グループ番号が負であるかパターン中で定義されたグループの数より大きければ、 IndexError 例外が送出されます。あるグループがパターンのマッチしなかった部分に含まれているなら、対応する結果は None です。あるグループがパターンの複数回マッチした部分に含まれているなら、最後のマッチが返されます。

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m.group(0)       # The entire match
'Isaac Newton'
>>> m.group(1)       # The first parenthesized subgroup.
'Isaac'
>>> m.group(2)       # The second parenthesized subgroup.
'Newton'
>>> m.group(1, 2)    # Multiple arguments give us a tuple.
('Isaac', 'Newton')

正規表現が (?P<name>...) 構文を使うなら、 groupN 引数はグループ名でグループを識別する文字列でも構いません。文字列引数がパターン中でグループ名として使われていなければ、 IndexError 例外が送出されます。

やや複雑な例:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.group('first_name')
'Malcolm'
>>> m.group('last_name')
'Reynolds'

名前付きグループはインデックスでも参照できます:

>>> m.group(1)
'Malcolm'
>>> m.group(2)
'Reynolds'

あるグループが複数回マッチすると、その最後のマッチにのみアクセスできます:

>>> m = re.match(r"(..)+", "a1b2c3")  # Matches 3 times.
>>> m.group(1)                        # Returns only the last match.
'c3'
Match.__getitem__(g)

これは m.group(g) と同等です。これでマッチの個別のグループに簡単にアクセスできます:

>>> m = re.match(r"(\w+) (\w+)", "Isaac Newton, physicist")
>>> m[0]       # The entire match
'Isaac Newton'
>>> m[1]       # The first parenthesized subgroup.
'Isaac'
>>> m[2]       # The second parenthesized subgroup.
'Newton'

Named groups are supported as well:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Isaac Newton")
>>> m['first_name']
'Isaac'
>>> m['last_name']
'Newton'

バージョン 3.6 で追加.

Match.groups(default=None)

このマッチの、1 からパターン中のグループ数まで、全てのサブグループを含むタプルを返します。default 引数はマッチに関係しなかったグループに使われます。デフォルトでは None です。

例えば:

>>> m = re.match(r"(\d+)\.(\d+)", "24.1632")
>>> m.groups()
('24', '1632')

少数位およびその後の全てをオプションにすると、全てのグループがマッチに関係するとは限りません。そういったグループは default 引数が与えられない限りデフォルトで None になります。

>>> m = re.match(r"(\d+)\.?(\d+)?", "24")
>>> m.groups()      # Second group defaults to None.
('24', None)
>>> m.groups('0')   # Now, the second group defaults to '0'.
('24', '0')
Match.groupdict(default=None)

このマッチの、全ての 名前付き サブグループを含む、サブグループ名をキーとする辞書を返します。 default 引数はマッチに関係しなかったグループに使われます。デフォルトは None です。例えば:

>>> m = re.match(r"(?P<first_name>\w+) (?P<last_name>\w+)", "Malcolm Reynolds")
>>> m.groupdict()
{'first_name': 'Malcolm', 'last_name': 'Reynolds'}
Match.start([group])
Match.end([group])

group がマッチした部分文字列の先頭と末尾のインデックスを返します。 group はデフォルトで 0 (マッチした部分文字列全体という意味) です。 group が存在してかつマッチには寄与していなかったなら -1 を返します。マッチオブジェクト m と、マッチに寄与したグループ g に対して、グループ g がマッチした部分文字列 (m.group(g) と等価です) は以下の通りです

m.string[m.start(g):m.end(g)]

group が空文字列にマッチしていたら m.start(group)m.end(group) と等しくなることに注意して下さい。例えば、 m = re.search('b(c?)', 'cba') とすると、 m.start(0) は 1 で、 m.end(0) は 2 で、 m.start(1)m.end(1) はともに 2 であり、 m.start(2)IndexError 例外を発生します。

メールアドレスから remove_this を取り除く例:

>>> email = "tony@tiremove_thisger.net"
>>> m = re.search("remove_this", email)
>>> email[:m.start()] + email[m.end():]
'tony@tiger.net'
Match.span([group])

マッチ m について、2 タプル (m.start(group), m.end(group)) を返します。 group がマッチに寄与していなければ、これは (-1, -1) です。 group はデフォルトで 0 、マッチ全体です。

Match.pos

正規表現オブジェクトsearch()match() に渡された pos の値です。これは正規表現エンジンがマッチを探し始める位置の文字列のインデックスです。

Match.endpos

正規表現オブジェクトsearch()match() に渡された endpos の値です。これは正規表現エンジンがそれ以上は進まない文字列のインデックスです。

Match.lastindex

最後にマッチしたキャプチャグループの整数インデックスです。どのグループも全くマッチしなければ None です。例えば、表現 (a)b((a)(b))((ab))'ab' に適用されると lastindex == 1 となり、同じ文字列に (a)(b) が適用されると lastindex == 2 となります。

Match.lastgroup

最後にマッチしたキャプチャグループの名前です。そのグループに名前がないか、どのグループも全くマッチしていなければ None です。

Match.re

このマッチインスタンスを生じさせた match() または search() メソッドの属する 正規表現オブジェクト です。

Match.string

match()search() へ渡された文字列です。

バージョン 3.7 で変更: copy.copy() および copy.deepcopy() をサポートするようになりました。マッチオブジェクトはアトミックであると見なされます。

正規表現の例

ペアの確認

この例では、マッチオブジェクトをより美しく表示するために、この補助関数を使用します:

def displaymatch(match):
    if match is None:
        return None
    return '<Match: %r, groups=%r>' % (match.group(), match.groups())

あなたがポーカープログラムを書いているとします。プレイヤーの手札は 5 文字の文字列によって表され、それぞれの文字が 1 枚のカードを表します。 "a" はエース、 "k" はキング、 "q" はクイーン、 "j" はジャック、 "t" は 10、そして "2" から "9" はその数字のカードを表します。

与えられた文字列が有効な手札であるか見るには、以下のようにできます:

>>> valid = re.compile(r"^[a2-9tjqk]{5}$")
>>> displaymatch(valid.match("akt5q"))  # Valid.
"<Match: 'akt5q', groups=()>"
>>> displaymatch(valid.match("akt5e"))  # Invalid.
>>> displaymatch(valid.match("akt"))    # Invalid.
>>> displaymatch(valid.match("727ak"))  # Valid.
"<Match: '727ak', groups=()>"

最後の手札、 "727ak" 、はペア、すなわち同じ値の 2 枚のカードを含みます。正規表現でこれにマッチするには、このように後方参照を使えます:

>>> pair = re.compile(r".*(.).*\1")
>>> displaymatch(pair.match("717ak"))     # Pair of 7s.
"<Match: '717', groups=('7',)>"
>>> displaymatch(pair.match("718ak"))     # No pairs.
>>> displaymatch(pair.match("354aa"))     # Pair of aces.
"<Match: '354aa', groups=('a',)>"

ペアになっているのがどのカードか調べるには、このようにマッチオブジェクトの group() メソッドを使えます:

>>> pair = re.compile(r".*(.).*\1")
>>> pair.match("717ak").group(1)
'7'

# Error because re.match() returns None, which doesn't have a group() method:
>>> pair.match("718ak").group(1)
Traceback (most recent call last):
  File "<pyshell#23>", line 1, in <module>
    re.match(r".*(.).*\1", "718ak").group(1)
AttributeError: 'NoneType' object has no attribute 'group'

>>> pair.match("354aa").group(1)
'a'

scanf() をシミュレートする

Python does not currently have an equivalent to scanf(). Regular expressions are generally more powerful, though also more verbose, than scanf() format strings. The table below offers some more-or-less equivalent mappings between scanf() format tokens and regular expressions.

scanf() Token

正規表現

%c

.

%5c

.{5}

%d

[-+]?\d+

%e, %E, %f, %g

[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?

%i

[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)

%o

[-+]?[0-7]+

%s

\S+

%u

\d+

%x, %X

[-+]?(0[xX])?[\dA-Fa-f]+

以下のような文字列からファイル名と数を抽出するには

/usr/sbin/sendmail - 0 errors, 4 warnings

you would use a scanf() format like

%s - %d errors, %d warnings

等価な正規表現はこうです

(\S+) - (\d+) errors, (\d+) warnings

search() vs. match()

Python offers different primitive operations based on regular expressions:

  • re.match() checks for a match only at the beginning of the string

  • re.search() checks for a match anywhere in the string (this is what Perl does by default)

  • re.fullmatch() checks for entire string to be a match

例えば:

>>> re.match("c", "abcdef")    # No match
>>> re.search("c", "abcdef")   # Match
<re.Match object; span=(2, 3), match='c'>
>>> re.fullmatch("p.*n", "python") # Match
<re.Match object; span=(0, 6), match='python'>
>>> re.fullmatch("r.*n", "python") # No match

'^' で始まる正規表現を search() で使って、マッチを文字列の先頭でのみに制限できます:

>>> re.match("c", "abcdef")    # No match
>>> re.search("^c", "abcdef")  # No match
>>> re.search("^a", "abcdef")  # Match
<re.Match object; span=(0, 1), match='a'>

ただし、 MULTILINE モードにおいて match() は文字列の先頭でのみマッチし、 '^' で始まる正規表現で search() を使うと各行の先頭でマッチすることに注意してください。

>>> re.match("X", "A\nB\nX", re.MULTILINE)  # No match
>>> re.search("^X", "A\nB\nX", re.MULTILINE)  # Match
<re.Match object; span=(4, 5), match='X'>

電話帳を作る

split() は渡されたパターンで文字列を分割してリストにします。このメソッドは、テキストデータをデータ構造に変換して、読みやすくしたり、以下の例で実演する電話帳作成のように Python で編集したりしやすくするのに、非常に役に立ちます。

最初に、入力を示します。通常、これはファイルからの入力になるでしょう。ここでは、3重引用符の書式とします。

>>> text = """Ross McFluff: 834.345.1254 155 Elm Street
...
... Ronald Heathmore: 892.345.3428 436 Finley Avenue
... Frank Burger: 925.541.7625 662 South Dogwood Way
...
...
... Heather Albrecht: 548.326.4584 919 Park Place"""

各項目は 1 つ以上の改行で区切られています。まずは文字列を変換して、空行でない各行を項目とするリストにします:

>>> entries = re.split("\n+", text)
>>> entries
['Ross McFluff: 834.345.1254 155 Elm Street',
'Ronald Heathmore: 892.345.3428 436 Finley Avenue',
'Frank Burger: 925.541.7625 662 South Dogwood Way',
'Heather Albrecht: 548.326.4584 919 Park Place']

そして各項目を、ファーストネーム、ラストネーム、電話番号、住所に分割してリストにします。分割パターンである空白文字は住所にも含まれるので、 split()maxsplit 引数を使います:

>>> [re.split(":? ", entry, 3) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155 Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436 Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662 South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919 Park Place']]

この :? パターンはラストネームの次のコロンにマッチして、分割結果のリストに出てこないようにします。 maxsplit4 にすれば、家屋番号とストリート名を分割できます:

>>> [re.split(":? ", entry, 4) for entry in entries]
[['Ross', 'McFluff', '834.345.1254', '155', 'Elm Street'],
['Ronald', 'Heathmore', '892.345.3428', '436', 'Finley Avenue'],
['Frank', 'Burger', '925.541.7625', '662', 'South Dogwood Way'],
['Heather', 'Albrecht', '548.326.4584', '919', 'Park Place']]

テキストの秘匿

sub() は出現する各パターンを文字列で、または関数の返り値で置き換えます。この例ではテキストを「秘匿」する関数と合わせて sub() を使うところを実演します。具体的には、文中の各単語について、最初と最後の文字を除く全ての文字をランダムに並び替えます:

>>> def repl(m):
...     inner_word = list(m.group(2))
...     random.shuffle(inner_word)
...     return m.group(1) + "".join(inner_word) + m.group(3)
...
>>> text = "Professor Abdolmalek, please report your absences promptly."
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Poefsrosr Aealmlobdk, pslaee reorpt your abnseces plmrptoy.'
>>> re.sub(r"(\w)(\w+)(\w)", repl, text)
'Pofsroser Aodlambelk, plasee reoprt yuor asnebces potlmrpy.'

全ての副詞を見つける

search() は最初のパターンにのみマッチしますが、 findall() は出現する 全ての パターンにマッチします。例えば、ライターがあるテキストの全ての副詞を見つけたいなら、以下のように findall() を使えます:

>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly\b", text)
['carefully', 'quickly']

全ての副詞とその位置を見つける

If one wants more information about all matches of a pattern than the matched text, finditer() is useful as it provides Match objects instead of strings. Continuing with the previous example, if a writer wanted to find all of the adverbs and their positions in some text, they would use finditer() in the following manner:

>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly\b", text):
...     print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly

Raw 文字列記法

Raw 文字列記法 (r"text") で正規表現をまともに保てます。それがなければ、正規表現中のバックスラッシュ ('\') を個々にバックスラッシュを前置してエスケープしなければなりません。例えば、以下の 2 行のコードは機能的に等価です:

>>> re.match(r"\W(.)\1\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<re.Match object; span=(0, 4), match=' ff '>

リテラルのバックスラッシュにマッチさせたいなら、正規表現中ではエスケープする必要があります。Raw 文字列記法では、r"\\" になります。Raw 文字列記法を用いないと、"\\\\" としなくてはならず、以下のコードは機能的に等価です:

>>> re.match(r"\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<re.Match object; span=(0, 1), match='\\'>

トークナイザを書く

トークナイザやスキャナ は文字列を解析し、文字のグループにカテゴリ分けします。これはコンパイラやインタプリタを書くうえで役立つ第一段階です。

テキストのカテゴリは正規表現で指定されます。この技法では、それらを一つのマスター正規表現に結合し、マッチの連続についてループします:

from typing import NamedTuple
import re

class Token(NamedTuple):
    type: str
    value: str
    line: int
    column: int

def tokenize(code):
    keywords = {'IF', 'THEN', 'ENDIF', 'FOR', 'NEXT', 'GOSUB', 'RETURN'}
    token_specification = [
        ('NUMBER',   r'\d+(\.\d*)?'),  # Integer or decimal number
        ('ASSIGN',   r':='),           # Assignment operator
        ('END',      r';'),            # Statement terminator
        ('ID',       r'[A-Za-z]+'),    # Identifiers
        ('OP',       r'[+\-*/]'),      # Arithmetic operators
        ('NEWLINE',  r'\n'),           # Line endings
        ('SKIP',     r'[ \t]+'),       # Skip over spaces and tabs
        ('MISMATCH', r'.'),            # Any other character
    ]
    tok_regex = '|'.join('(?P<%s>%s)' % pair for pair in token_specification)
    line_num = 1
    line_start = 0
    for mo in re.finditer(tok_regex, code):
        kind = mo.lastgroup
        value = mo.group()
        column = mo.start() - line_start
        if kind == 'NUMBER':
            value = float(value) if '.' in value else int(value)
        elif kind == 'ID' and value in keywords:
            kind = value
        elif kind == 'NEWLINE':
            line_start = mo.end()
            line_num += 1
            continue
        elif kind == 'SKIP':
            continue
        elif kind == 'MISMATCH':
            raise RuntimeError(f'{value!r} unexpected on line {line_num}')
        yield Token(kind, value, line_num, column)

statements = '''
    IF quantity THEN
        total := total + price * quantity;
        tax := price * 0.05;
    ENDIF;
'''

for token in tokenize(statements):
    print(token)

このトークナイザは以下の出力を作成します:

Token(type='IF', value='IF', line=2, column=4)
Token(type='ID', value='quantity', line=2, column=7)
Token(type='THEN', value='THEN', line=2, column=16)
Token(type='ID', value='total', line=3, column=8)
Token(type='ASSIGN', value=':=', line=3, column=14)
Token(type='ID', value='total', line=3, column=17)
Token(type='OP', value='+', line=3, column=23)
Token(type='ID', value='price', line=3, column=25)
Token(type='OP', value='*', line=3, column=31)
Token(type='ID', value='quantity', line=3, column=33)
Token(type='END', value=';', line=3, column=41)
Token(type='ID', value='tax', line=4, column=8)
Token(type='ASSIGN', value=':=', line=4, column=12)
Token(type='ID', value='price', line=4, column=15)
Token(type='OP', value='*', line=4, column=21)
Token(type='NUMBER', value=0.05, line=4, column=23)
Token(type='END', value=';', line=4, column=27)
Token(type='ENDIF', value='ENDIF', line=5, column=4)
Token(type='END', value=';', line=5, column=9)
[Frie09]

Friedl, Jeffrey. Mastering Regular Expressions. 3rd ed., O'Reilly Media, 2009. 当書の第三版ではもはや Python についてまったく取り扱っていませんが、初版では良い正規表現を書くことを綿密に取り扱っていました。