6.2。 NS —正規表現操作
ソースコード: :source: `Lib / re.py`
このモジュールは、Perlで見られるものと同様の正規表現マッチング操作を提供します。
検索するパターンと文字列はどちらも、Unicode文字列( str )と8ビット文字列( bytes )のどちらでもかまいません。 ただし、Unicode文字列と8ビット文字列を混在させることはできません。つまり、Unicode文字列をバイトパターンと一致させることはできません。その逆も同様です。 同様に、置換を要求する場合、置換文字列はパターンと検索文字列の両方と同じタイプである必要があります。
正規表現では、バックスラッシュ文字('\'
)を使用して、特殊形式を示したり、特殊な意味を呼び出さずに特殊文字を使用できるようにします。 これは、文字列リテラルで同じ目的のためにPythonが同じ文字を使用することと衝突します。 たとえば、リテラルの円記号と一致させるには、正規表現を\\
にする必要があり、各円記号を\\
として表す必要があるため、パターン文字列として'\\\\'
を記述する必要があります。 ]通常のPython文字列リテラル内。
解決策は、正規表現パターンにPythonの生の文字列表記を使用することです。 バックスラッシュは、'r'
で始まる文字列リテラルでは特別な方法で処理されません。 したがって、r"\n"
は'\'
と'n'
を含む2文字の文字列であり、"\n"
は改行を含む1文字の文字列です。 通常、パターンはこの生の文字列表記を使用してPythonコードで表現されます。
ほとんどの正規表現操作は、コンパイルされた正規表現のモジュールレベルの関数およびメソッドとして使用できることに注意してください。 これらの関数は、最初に正規表現オブジェクトをコンパイルする必要はありませんが、いくつかの微調整パラメーターを見逃しているショートカットです。
6.2.1。 正規表現の構文
正規表現(またはRE)は、それに一致する文字列のセットを指定します。 このモジュールの関数を使用すると、特定の文字列が特定の正規表現に一致するかどうか(または、特定の正規表現が特定の文字列に一致するかどうかを確認できます。これは同じことです)。
正規表現を連結して、新しい正規表現を形成できます。 A と B が両方とも正規表現である場合、 AB も正規表現です。 一般に、文字列 p が A と一致し、別の文字列 q が B と一致する場合、文字列 pq はABに一致します。 これは、 A または B に優先順位の低い操作が含まれていない限り当てはまります。 A と B の間の境界条件。 または番号付きのグループ参照があります。 したがって、複雑な式は、ここで説明するような単純なプリミティブ式から簡単に構築できます。 正規表現の理論と実装の詳細については、Friedlの本 [Frie09] 、またはコンパイラの構築に関するほとんどすべての教科書を参照してください。
正規表現の形式について簡単に説明します。 詳細およびより穏やかなプレゼンテーションについては、正規表現HOWTO を参照してください。
正規表現には、特殊文字と通常の文字の両方を含めることができます。 'A'
、'a'
、'0'
などのほとんどの通常の文字は、最も単純な正規表現です。 それらは単に自分自身と一致します。 通常の文字を連結できるため、last
は文字列'last'
と一致します。 (このセクションの残りの部分では、REをthis special style
で記述します。通常は引用符なしで、一致する文字列は'in single quotes'
です。)
'|'
や'('
などの一部の文字は特別です。 特殊文字は、通常の文字のクラスを表すか、それらの周りの正規表現がどのように解釈されるかに影響を与えます。
繰り返し修飾子(*
、+
、?
、{m,n}
など)を直接ネストすることはできません。 これにより、貪欲でない修飾子の接尾辞?
や、他の実装の他の修飾子とのあいまいさが回避されます。 2番目の繰り返しを内側の繰り返しに適用するには、括弧を使用できます。 たとえば、式(?:a{6})*
は、6つの'a'
文字の倍数に一致します。
特殊文字は次のとおりです。
.
- (ドット)デフォルトモードでは、これは改行以外のすべての文字に一致します。 DOTALL フラグが指定されている場合、これは改行を含むすべての文字に一致します。
^
- (キャレット)文字列の先頭に一致し、 MULTILINE モードでは各改行の直後にも一致します。
$
- 文字列の終わりまたは文字列の終わりの改行の直前に一致し、 MULTILINE モードでは改行の前にも一致します。
foo
は「foo」と「foobar」の両方に一致しますが、正規表現foo$
は「foo」にのみ一致します。 さらに興味深いことに、'foo1\nfoo2\n'
でfoo.$
を検索すると、通常は「foo2」に一致しますが、 MULTILINE モードでは「foo1」に一致します。'foo\n'
で単一の$
を検索すると、2つの(空の)一致が見つかります。1つは改行の直前、もう1つは文字列の最後です。
*
- 結果のREを、可能な限り多くの繰り返しで、前のREの0回以上の繰り返しと一致させます。
ab*
は、「a」、「ab」、または「a」の後に任意の数の「b」が続くものと一致します。
+
- 結果のREを前のREの1回以上の繰り返しと一致させます。
ab+
は、「a」の後にゼロ以外の数の「b」が続くものと一致します。 'a'だけでは一致しません。
?
- 結果のREを、前のREの0回または1回の繰り返しと一致させます。
ab?
は「a」または「ab」のいずれかに一致します。
*?
、+?
、??
'*'
、'+'
、および'?'
修飾子はすべて greedy です。 それらは可能な限り多くのテキストに一致します。 この動作が望ましくない場合があります。 RE<.*>
が'<a> b <c>'
と一致する場合、'<a>'
だけでなく、文字列全体と一致します。 修飾子の後に?
を追加すると、欲張りでないまたは最小の方法で一致が実行されます。 可能な限り少数の文字が一致します。 RE<.*?>
を使用すると、'<a>'
のみに一致します。
{m}
- 前のREの m コピーを正確に一致させる必要があることを指定します。 一致が少ないと、RE全体が一致しなくなります。 たとえば、
a{6}
は、6つの'a'
文字と正確に一致しますが、5つとは一致しません。 {m,n}
- 結果のREを、前のREの m から n の繰り返しに一致させ、可能な限り多くの繰り返しに一致させようとします。 たとえば、
a{3,5}
は3〜5個の'a'
文字に一致します。 m を省略すると、ゼロの下限が指定され、 n を省略すると、無限の上限が指定されます。 例として、a{4,}b
は'aaaab'
または1000個の'a'
文字の後に'b'
が続きますが、'aaab'
とは一致しません。 カンマは省略できません。省略しないと、修飾子が前述の形式と混同されます。 {m,n}?
- 結果のREを前のREの m から n の繰り返しに一致させ、少数のの繰り返しとして一致させようとします。 これは、前の修飾子の貪欲でないバージョンです。 たとえば、6文字の文字列
'aaaaaa'
では、a{3,5}
は5つの'a'
文字に一致しますが、a{3,5}?
は3文字にのみ一致します。
\
特殊文字をエスケープする(
'*'
、'?'
などの文字との一致を許可する)か、特殊シーケンスを通知します。 特別なシーケンスについては、以下で説明します。パターンを表現するために生の文字列を使用していない場合、Pythonは文字列リテラルのエスケープシーケンスとしてバックスラッシュも使用することに注意してください。 エスケープシーケンスがPythonのパーサーによって認識されない場合、バックスラッシュとそれに続く文字が結果の文字列に含まれます。 ただし、Pythonが結果のシーケンスを認識する場合は、円記号を2回繰り返す必要があります。 これは複雑で理解しにくいため、最も単純な式を除くすべての式に生の文字列を使用することを強くお勧めします。
[]
文字のセットを示すために使用されます。 セットで:
文字は個別にリストできます。例:
[amk]
は、'a'
、'm'
、または'k'
と一致します。
文字の範囲は、2文字を指定し、
'-'
で区切ることで示すことができます。たとえば、[a-z]
は小文字のASCII文字に一致し、[0-5][0-9]
は2桁すべてに一致します。00
から59
までの数字、および[0-9A-Fa-f]
は、任意の16進数に一致します。-
がエスケープされている場合(例:[a\-z]
)または最初または最後の文字として配置されている場合(例:[-a]
または[a-]
)、リテラル'-'
と一致します。特殊文字は、セット内で特別な意味を失います。 たとえば、
[(+*)]
は、リテラル文字'('
、'+'
、'*'
、または')'
のいずれかに一致します。
範囲内にない文字は、セットを補完することで一致させることができます。 セットの最初の文字が
'^'
の場合、セット内のではないのすべての文字が一致します。 たとえば、[^5]
は'5'
以外のすべての文字と一致し、[^^]
は'^'
以外のすべての文字と一致します。^
は、セットの最初の文字でない場合、特別な意味はありません。セット内のリテラル
']'
と一致させるには、その前に円記号を付けるか、セットの先頭に配置します。 たとえば、[()[\]{}]
と[]()[{}]
の両方が括弧に一致します。
|
A|B
( A および B は任意のREにすることができます)は、 A または B のいずれかに一致する正規表現を作成します。 ]。 このようにして、'|'
で任意の数のREを区切ることができます。 これは、グループ内でも使用できます(以下を参照)。 ターゲット文字列がスキャンされると、'|'
で区切られたREが左から右に試行されます。 1つのパターンが完全に一致すると、そのブランチが受け入れられます。 つまり、 A が一致すると、全体的な一致が長くなったとしても、 B はそれ以上テストされません。 言い換えれば、'|'
演算子は決して貪欲ではありません。 リテラル'|'
と一致させるには、\|
を使用するか、[|]
のように文字クラスで囲みます。
(...)
- 括弧内の正規表現に一致し、グループの開始と終了を示します。 グループの内容は、一致が実行された後に取得でき、文字列の後半で、以下で説明する
\number
特殊シーケンスと一致させることができます。 リテラル'('
または')'
と一致させるには、\(
または\)
を使用するか、文字クラス[(]
、[)]
。
(?...)
- これは拡張表記です(
'('
に続く'?'
は、それ以外の場合は意味がありません)。'?'
の後の最初の文字は、構成の意味とさらなる構文が何であるかを決定します。 拡張機能は通常、新しいグループを作成しません。(?P<name>...)
はこのルールの唯一の例外です。 現在サポートされている拡張機能は次のとおりです。 (?aiLmsux)
- (セット
'a'
、'i'
、'L'
、'm'
、's'
、'u'
からの1つ以上の文字、'x'
。)グループは空の文字列と一致します。 文字は対応するフラグを設定します: re.A (ASCIIのみの一致)、 re.I (大文字と小文字を区別しない)、 re.L (ロケールに依存) 、 re.M (複数行)、 re.S (ドットはすべてに一致)、re.U
(Unicode一致)、および re.X [ X400X](verbose)、正規表現全体。 (フラグはモジュールの内容で説明されています。)これは、フラグ引数をに渡す代わりに、正規表現の一部としてフラグを含める場合に役立ちます。 re.compile()関数。 式文字列では、最初にフラグを使用する必要があります。
(?:...)
通常の括弧の非キャプチャバージョン。 括弧内の正規表現に一致しますが、グループに一致する部分文字列は、一致を実行した後、またはパターンの後半で参照された後に取得できません。
(?imsx-imsx:...)
(セット
'i'
、'm'
、's'
、'x'
からのゼロ以上の文字、オプションで'-'
の後に1つ以上の文字同じセットからの文字。)文字は、対応するフラグを設定または削除します: re.I (大文字と小文字を区別しない)、 re.M (複数行)、 re。式の一部として、S (ドットはすべてに一致)、および re.X (詳細)。 (フラグはモジュールの内容で説明されています。)バージョン3.6の新機能。
(?P<name>...)
通常の括弧に似ていますが、グループに一致するサブストリングには、シンボリックグループ名 name を介してアクセスできます。 グループ名は有効なPython識別子である必要があり、各グループ名は正規表現内で1回だけ定義する必要があります。 シンボリックグループも、グループに名前が付けられていないかのように、番号が付けられたグループです。
名前付きグループは、3つのコンテキストで参照できます。 パターンが
(?P<quote>['"]).*?(?P=quote)
の場合(つまり 一重引用符または二重引用符で引用された文字列に一致する):グループ「quote」への参照のコンテキスト
それを参照する方法
同じパターン自体で
(?P=quote)
(図のように)\1
一致オブジェクト m を処理するとき
m.group('quote')
m.end('quote')
(など)
re.sub()
の repl 引数に渡される文字列内\g<quote>
\g<1>
\1
(?P=name)
- 名前付きグループへの後方参照。 name という名前の以前のグループが一致したテキストと一致します。
(?#...)
- A comment; the contents of the parentheses are simply ignored.
(?=...)
...
が次に一致する場合に一致しますが、文字列を消費しません。 これは、先読みアサーションと呼ばれます。 たとえば、Isaac (?=Asimov)
は、'Asimov'
が後に続く場合にのみ、'Isaac '
と一致します。
(?!...)
...
が次に一致しない場合に一致します。 これはネガティブ先読みアサーションです。 たとえば、Isaac (?!Asimov)
はではなくの後に'Asimov'
が続く場合にのみ、'Isaac '
と一致します。
(?<=...)
文字列内の現在の位置の前に、現在の位置で終了する
...
の一致がある場合に一致します。 これは、ポジティブルックビハインドアサーションと呼ばれます。(?<=abc)def
は、'abcdef'
で一致するものを見つけます。これは、後読みが3文字をバックアップし、含まれているパターンが一致するかどうかを確認するためです。 含まれるパターンは、一定の長さの文字列にのみ一致する必要があります。つまり、abc
またはa|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で変更:固定長のグループ参照のサポートが追加されました。
(?<!...)
- 文字列内の現在の位置の前に
...
の一致がない場合に一致します。 これは、ネガティブルックビハインドアサーションと呼ばれます。 ポジティブルックビハインドアサーションと同様に、含まれるパターンは、一定の長さの文字列にのみ一致する必要があります。 ネガティブルックビハインドアサーションで始まるパターンは、検索対象の文字列の先頭で一致する場合があります。 (?(id/name)yes-pattern|no-pattern)
- 指定された id または name のグループが存在する場合は、
yes-pattern
と一致させ、存在しない場合はno-pattern
と一致させようとします。no-pattern
はオプションであり、省略できます。 たとえば、(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$)
はメールの一致パターンが不十分であり、'<[email protected]>'
および'[email protected]'
と一致しますが、'<[email protected]'
または [ X142X]。
特別なシーケンスは、'\'
と以下のリストの文字で構成されます。 通常の文字がASCII数字またはASCII文字でない場合、結果のREは2番目の文字と一致します。 たとえば、\$
は文字'$'
と一致します。
\number
- 同じ番号のグループの内容と一致します。 グループには1から始まる番号が付けられます。 たとえば、
(.+) \1
は'the the'
または'55 55'
と一致しますが、'thethe'
とは一致しません(グループの後のスペースに注意してください)。 この特別なシーケンスは、最初の99グループの1つと一致する場合にのみ使用できます。 number の最初の桁が0の場合、または number が3オクタル桁の長さの場合、グループ一致としてではなく、8進数値 numberの文字として解釈されます。 。 文字クラスの'['
および']'
内では、すべての数値エスケープは文字として扱われます。
\A
- 文字列の先頭でのみ一致します。
\b
空の文字列に一致しますが、単語の最初または最後にのみ一致します。 単語は、単語文字のシーケンスとして定義されます。 正式には、
\b
は\w
と\W
文字の間(またはその逆)、または\w
と先頭/の間の境界として定義されていることに注意してください。文字列の終わり。 つまり、r'\bfoo\b'
は'foo'
、'foo.'
、'(foo)'
、'bar foo baz'
と一致しますが、'foobar'
または [ X103X]。デフォルトでは、Unicode英数字はUnicodeパターンで使用されるものですが、これは ASCII フラグを使用して変更できます。 LOCALE フラグが使用されている場合、単語の境界は現在のロケールによって決定されます。 文字範囲内では、
\b
は、Pythonの文字列リテラルとの互換性のために、バックスペース文字を表します。
\B
- 空の文字列に一致しますが、単語の先頭または末尾がではなくの場合に限ります。 つまり、
r'py\B'
は'python'
、'py3'
、'py2'
と一致しますが、'py'
、'py.'
、または'py!'
。\B
は\b
の正反対であるため、Unicodeパターンの単語文字はUnicode英数字またはアンダースコアですが、 ASCII フラグを使用して変更できます。 LOCALE フラグが使用されている場合、単語の境界は現在のロケールによって決定されます。
\d
- ;; Unicode(str)パターンの場合:
- 任意のUnicode10進数(つまり、Unicode文字カテゴリ[Nd]内の任意の文字)に一致します。 これには、
[0-9]
、および他の多くの数字が含まれます。 ASCII フラグを使用すると、[0-9]
のみが一致します(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[0-9]
を使用することをお勧めします)。 。 - 8ビット(バイト)パターンの場合:
- 任意の10進数に一致します。 これは
[0-9]
と同等です。
\D
- 10進数以外の任意の文字に一致します。 これは
\d
の反対です。 ASCII フラグを使用すると、これは[^0-9]
と同等になります(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[^0-9]
を使用する方が適切な場合があります。選択)。
\s
- ;; Unicode(str)パターンの場合:
- Unicode空白文字(
[ \t\n\r\f\v]
、および他の多くの文字、たとえば、多くの言語のタイポグラフィ規則で義務付けられている改行なしスペースを含む)に一致します。 ASCII フラグが使用されている場合、[ \t\n\r\f\v]
のみが一致します(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[ \t\n\r\f\v]
を使用することをお勧めします。 )。 - 8ビット(バイト)パターンの場合:
- ASCII文字セットで空白と見なされる文字に一致します。 これは
[ \t\n\r\f\v]
と同等です。
\S
- 空白文字ではない任意の文字に一致します。 これは
\s
の反対です。 ASCII フラグを使用すると、これは[^ \t\n\r\f\v]
と同等になります(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[^ \t\n\r\f\v]
を使用する方が適切な場合があります。選択)。
\w
- ;; Unicode(str)パターンの場合:
- Unicode単語文字に一致します。 これには、数字やアンダースコアだけでなく、任意の言語の単語の一部となる可能性のあるほとんどの文字が含まれます。 ASCII フラグが使用されている場合、
[a-zA-Z0-9_]
のみが一致します(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[a-zA-Z0-9_]
を使用することをお勧めします。 )。 - 8ビット(バイト)パターンの場合:
- ASCII文字セットで英数字と見なされる文字に一致します。 これは
[a-zA-Z0-9_]
と同等です。 LOCALE フラグが使用されている場合、現在のロケールで英数字と見なされる文字とアンダースコアに一致します。
\W
- 単語文字ではない任意の文字に一致します。 これは
\w
の反対です。 ASCII フラグを使用すると、これは[^a-zA-Z0-9_]
と同等になります(ただし、フラグは正規表現全体に影響するため、このような場合は、明示的な[^a-zA-Z0-9_]
を使用する方が適切な場合があります。選択)。 LOCALE フラグが使用されている場合、現在のロケールで英数字と見なされる文字とアンダースコアに一致します。
\Z
- 文字列の最後でのみ一致します。
Python文字列リテラルでサポートされている標準のエスケープのほとんどは、正規表現パーサーでも受け入れられます。
\a \b \f \n
\r \t \u \U
\v \x \\
(\b
は単語の境界を表すために使用され、文字クラス内でのみ「バックスペース」を意味することに注意してください。)
'\u'
および'\U'
エスケープシーケンスは、Unicodeパターンでのみ認識されます。 バイトパターンでは、それらはエラーです。
オクタルエスケープは限定された形式で含まれています。 最初の桁が0の場合、または3桁の8進数がある場合は、8進数のエスケープと見なされます。 それ以外の場合は、グループ参照です。 文字列リテラルの場合、8進エスケープの長さは常に最大3桁です。
バージョン3.3で変更: '\u'
および'\U'
エスケープシーケンスが追加されました。
バージョン3.6で変更: '\'
とASCII文字で構成される不明なエスケープがエラーになりました。
6.2.2。 モジュールの内容
このモジュールは、いくつかの関数、定数、および例外を定義します。 一部の関数は、コンパイルされた正規表現のフル機能のメソッドの簡略版です。 ほとんどの重要なアプリケーションは、常にコンパイルされた形式を使用します。
バージョン3.6での変更:フラグ定数は、 enum.IntFlag のサブクラスであるRegexFlag
のインスタンスになりました。
- re.compile(pattern, flags=0)
正規表現パターンを正規表現オブジェクトにコンパイルします。これは、 match()、 search()、および以下で説明するその他のメソッドを使用したマッチングに使用できます。 。
式の動作は、 flags 値を指定することで変更できます。 値は、ビット単位のOR(
|
演算子)を使用して組み合わせた、次の変数のいずれかになります。シーケンス
prog = re.compile(pattern) result = prog.match(string)
と同等です
result = re.match(pattern, string)
ただし、 re.compile()を使用し、結果の正規表現オブジェクトを再利用のために保存すると、式が1つのプログラムで複数回使用される場合に効率的です。
ノート
re.compile()に渡された最新のパターンのコンパイル済みバージョンとモジュールレベルのマッチング関数がキャッシュされるため、一度に少数の正規表現のみを使用するプログラムは、正規表現のコンパイルについて心配する必要はありません。式。
- re.A
re.ASCII \w
、\W
、\b
、\B
、\d
、\D
、\s
、および\S
は、完全なUnicodeマッチングではなく、ASCIIのみのマッチングを実行します。 これはUnicodeパターンでのみ意味があり、バイトパターンでは無視されます。 インラインフラグ(?a)
に対応します。下位互換性のために、
re.U
フラグ(およびその同義語re.UNICODE
とその埋め込み対応物(?u)
)はまだ存在しますが、一致するものが文字列のデフォルトのUnicode(およびバイトのUnicodeマッチングは許可されていません)。
- re.DEBUG
- コンパイルされた式に関するデバッグ情報を表示します。 対応するインラインフラグはありません。
- re.I
re.IGNORECASE 大文字と小文字を区別しないマッチングを実行します。
[A-Z]
のような式も小文字に一致します。 re.ASCII フラグを使用して非ASCII一致を無効にしない限り、完全なUnicode一致(Ü
一致ü
など)も機能します。 re.LOCALE フラグも使用されていない限り、現在のロケールはこのフラグの効果を変更しません。 インラインフラグ(?i)
に対応します。Unicodeパターン
[a-z]
または[A-Z]
を IGNORECASE フラグと組み合わせて使用すると、52個のASCII文字と4個の追加の非ASCII文字に一致することに注意してください。 İ '(U + 0130、上にドットが付いたラテン大文字I)、'ı '(U + 0131、ドットなしのラテン小文字i)、' ſ '(U + 017F、ラテン小文字の長いs)、および' K '( U + 212A、ケルビン記号)。 ASCII フラグが使用されている場合、文字「a」から「z」および「A」から「Z」のみが一致します(ただし、フラグは正規表現全体に影響するため、このような場合は明示的な[ X175X] がより良い選択かもしれません)。
- re.L
re.LOCALE \w
、\W
、\b
、\B
、および大文字と小文字を区別しないマッチングを現在のロケールに依存させます。 このフラグは、バイトパターンでのみ使用できます。 ロケールメカニズムは非常に信頼性が低く、一度に1つの「カルチャ」のみを処理し、8ビットロケールでのみ機能するため、このフラグの使用はお勧めしません。 Unicodeマッチングは、Python 3でUnicode(str)パターンに対してデフォルトですでに有効になっており、さまざまなロケール/言語を処理できます。 インラインフラグ(?L)
に対応します。
- re.M
re.MULTILINE
- 指定すると、パターン文字
'^'
は、文字列の先頭と各行の先頭(各改行の直後)で一致します。 パターン文字'$'
は、文字列の終わりと各行の終わり(各改行の直前)で一致します。 デフォルトでは、'^'
は文字列の先頭でのみ一致し、'$'
は文字列の末尾で、文字列の末尾の改行(存在する場合)の直前でのみ一致します。 インラインフラグ(?m)
に対応します。
- re.S
re.DOTALL
'.'
特殊文字を、改行を含むすべての文字と完全に一致させます。 このフラグがないと、'.'
は改行を除くすべてのと一致します。 インラインフラグ(?s)
に対応します。
- re.X
re.VERBOSE このフラグを使用すると、パターンの論理セクションを視覚的に分離してコメントを追加できるため、見栄えがよく読みやすい正規表現を記述できます。 パターン内の空白は、文字クラス内、エスケープされていない円記号が前にある場合、または
*?
、(?:
、(?P<...>
などのトークン内の場合を除いて無視されます。 文字クラスに含まれておらず、前にエスケープされていない円記号が付いていない#
が行に含まれている場合、そのような#
の左端から行末までのすべての文字が無視されます。これは、10進数に一致する次の2つの正規表現オブジェクトが機能的に等しいことを意味します。
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.search(pattern, string, flags=0)
- string をスキャンして、正規表現 pattern が一致する最初の場所を探し、対応する matchオブジェクトを返します。 文字列内のどの位置もパターンに一致しない場合は、
None
を返します。 これは、文字列のある時点で長さがゼロの一致を見つけることとは異なることに注意してください。
- re.match(pattern, string, flags=0)
文字列の先頭の0文字以上が正規表現パターンと一致する場合、対応する一致オブジェクトを返します。 文字列がパターンと一致しない場合は、
None
を返します。 これは長さゼロの一致とは異なることに注意してください。MULTILINE モードでも、 re.match()は文字列の先頭でのみ一致し、各行の先頭では一致しないことに注意してください。
どこかで一致するものを見つけたい場合ストリング 、 使用する探す() 代わりに( search()対。 マッチ() )。
- re.fullmatch(pattern, string, flags=0)
文字列全体が正規表現パターンと一致する場合、対応する一致オブジェクトを返します。 文字列がパターンと一致しない場合は、
None
を返します。 これは長さゼロの一致とは異なることに注意してください。バージョン3.4の新機能。
- re.split(pattern, string, maxsplit=0, flags=0)
文字列をパターンの出現によって分割します。 pattern でキャプチャ括弧が使用されている場合、パターン内のすべてのグループのテキストも結果のリストの一部として返されます。 maxsplit がゼロ以外の場合、最大で 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', '...', '']
このように、セパレータコンポーネントは、結果リスト内の同じ相対インデックスで常に検出されます。
ノート
split()は現在、空のパターンマッチで文字列を分割しません。 例えば:
>>> re.split('x*', 'axbc') ['a', 'bc']
'x*'
も 'a'の前、 'b'と 'c'の間、および 'c'の後に0'x 'と一致しますが、現在これらの一致は無視されます。 正しい動作(つまり 空の一致でも分割して[, 'a', 'b', 'c', ]
)を返すことは、Pythonの将来のバージョンで実装されますが、これは後方互換性のない変更であるため、その間に FutureWarning が発生します。空の文字列にのみ一致するパターンは、現在、文字列を分割することはありません。 これは予想される動作と一致しないため、Python3.5以降で ValueError が発生します。
>>> re.split("^$", "foo\n\nbar\n", flags=re.M) Traceback (most recent call last): File "<stdin>", line 1, in <module> ... ValueError: split() requires a non-empty pattern match.
バージョン3.1で変更:オプションのflags引数を追加しました。
バージョン3.5で変更:空の文字列に一致する可能性のあるパターンを分割すると、警告が発生するようになりました。 空の文字列にのみ一致するパターンが拒否されるようになりました。
- re.findall(pattern, string, flags=0)
string 内の pattern の重複しないすべての一致を文字列のリストとして返します。 文字列は左から右にスキャンされ、一致するものが見つかった順序で返されます。 パターンに1つ以上のグループが存在する場合は、グループのリストを返します。 パターンに複数のグループがある場合、これはタプルのリストになります。 空の一致が結果に含まれます。
ノート
現在の実装の制限により、空の一致に続く文字は次の一致に含まれないため、
findall(r'^|\w+', 'two words')
は[, 'wo', 'words']
を返します(「t」を見逃していることに注意してください)。 これはPython3.7で変更されています。
- re.finditer(pattern, string, flags=0)
- イテレータを返し、文字列内のRE パターンの重複しないすべての一致に対して一致オブジェクトを生成します。 文字列は左から右にスキャンされ、一致するものが見つかった順序で返されます。 空の一致が結果に含まれます。 findall()に関する注記も参照してください。
- re.sub(pattern, repl, string, count=0, flags=0)
string の pattern の左端の重複しないオカレンスを、置換 repl で置き換えて取得した文字列を返します。 パターンが見つからない場合、 string は変更されずに返されます。 repl は文字列または関数にすることができます。 文字列の場合、その中の円記号エスケープはすべて処理されます。 つまり、
\n
は単一の改行文字に変換され、\r
はキャリッジリターンに変換されます。\&
などの不明なエスケープはそのままにしておきます。\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{'
repl が関数の場合、 pattern が重複しないたびに呼び出されます。 この関数は、単一の match object 引数を取り、置換文字列を返します。 例えば:
>>> 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'
パターンは、文字列またはパターンオブジェクトの場合があります。
オプションの引数 count は、置き換えられるパターンオカレンスの最大数です。 count は負でない整数でなければなりません。 省略またはゼロの場合、すべてのオカレンスが置き換えられます。 パターンの空の一致は、前の一致に隣接していない場合にのみ置き換えられるため、
sub('x*', '-', 'abc')
は'-a-b-c-'
を返します。文字列型 repl 引数では、上記の文字エスケープと後方参照に加えて、
\g<name>
は、name
という名前のグループと一致するサブ文字列を使用します。これは、(?P<name>...)
構文。\g<number>
は対応するグループ番号を使用します。 したがって、\g<2>
は\2
と同等ですが、\g<2>0
などの置き換えではあいまいではありません。\20
は、グループ2への参照の後にリテラル文字'0'
が続くのではなく、グループ20への参照として解釈されます。 後方参照\g<0>
は、REと一致する部分文字列全体を置き換えます。バージョン3.1で変更:オプションのflags引数を追加しました。
バージョン3.5で変更:一致しないグループは空の文字列に置き換えられます。
バージョン3.6で変更:
'\'
とASCII文字で構成されるパターンの不明なエスケープがエラーになりました。
- re.subn(pattern, repl, string, count=0, flags=0)
sub()と同じ操作を実行しますが、タプル
(new_string, number_of_subs_made)
を返します。バージョン3.1で変更:オプションのflags引数を追加しました。
バージョン3.5で変更:一致しないグループは空の文字列に置き換えられます。
- re.escape(pattern)
ASCII文字、数字、および
'_'
を除く、パターンのすべての文字をエスケープします。 これは、正規表現のメタ文字が含まれている可能性のある任意のリテラル文字列に一致させる場合に役立ちます。 例えば:>>> print(re.escape('python.exe')) python\.exe >>> 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で変更:
'_'
文字はエスケープされなくなりました。
- re.purge()
- 正規表現キャッシュをクリアします。
- exception re.error(msg, pattern=None, pos=None)
ここで関数の1つに渡された文字列が有効な正規表現ではない場合(たとえば、一致しない括弧が含まれている場合)、またはコンパイルまたは一致中に他のエラーが発生した場合に発生する例外。 文字列にパターンに一致するものが含まれていない場合でも、エラーになることはありません。 エラーインスタンスには、次の追加属性があります。
- msg
フォーマットされていないエラーメッセージ。
- pattern
正規表現パターン。
- pos
コンパイルが失敗した pattern のインデックス(
None
の可能性があります)。
- lineno
pos に対応する行(
None
の場合があります)。
- colno
pos に対応する列(
None
の場合があります)。
バージョン3.5で変更:追加の属性を追加しました。
6.2.3。 正規表現オブジェクト
コンパイルされた正規表現オブジェクトは、次のメソッドと属性をサポートします。
- regex.search(string[, pos[, endpos]])
文字列をスキャンして、この正規表現が一致する最初の場所を探し、対応する一致オブジェクトを返します。 文字列内のどの位置もパターンに一致しない場合は、
None
を返します。 これは、文字列のある時点で長さがゼロの一致を見つけることとは異なることに注意してください。オプションの2番目のパラメータ pos は、検索を開始する文字列のインデックスを提供します。 デフォルトは
0
です。 これは、文字列をスライスすることと完全に同等ではありません。'^'
パターン文字は、文字列の実際の先頭と改行の直後の位置で一致しますが、検索を開始するインデックスで一致するとは限りません。オプションのパラメータ endpos は、文字列が検索される範囲を制限します。 文字列が endpos 文字の長さであるかのようになるため、 pos から
endpos - 1
までの文字のみが一致するものを検索します。 endpos が pos より小さい場合、一致するものは見つかりません。 それ以外の場合、 rx がコンパイルされた正規表現オブジェクトである場合、rx.search(string, 0, 50)
はrx.search(string[:50], 0)
と同等です。>>> pattern = re.compile("d") >>> pattern.search("dog") # Match at index 0 <_sre.SRE_Match object; span=(0, 1), match='d'> >>> pattern.search("dog", 1) # No match; search doesn't include the "d"
- regex.match(string[, pos[, endpos]])
string の beginning にある0個以上の文字がこの正規表現に一致する場合、対応する一致オブジェクトを返します。 文字列がパターンと一致しない場合は、
None
を返します。 これは長さゼロの一致とは異なることに注意してください。オプションの 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". <_sre.SRE_Match object; span=(1, 2), match='o'>
どこかで一致するものを見つけたい場合ストリング 、 使用する探す() 代わりに( search()対。 マッチ() )。
- regex.fullmatch(string[, pos[, endpos]])
文字列全体がこの正規表現に一致する場合は、対応する一致オブジェクトを返します。 文字列がパターンと一致しない場合は、
None
を返します。 これは長さゼロの一致とは異なることに注意してください。オプションの 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. <_sre.SRE_Match object; span=(1, 3), match='og'>
バージョン3.4の新機能。
- regex.split(string, maxsplit=0)
- コンパイルされたパターンを使用して、 split()関数と同じです。
- regex.findall(string[, pos[, endpos]])
- findall()関数と同様に、コンパイルされたパターンを使用しますが、 searchのように検索領域を制限するオプションの pos および endpos パラメーターも受け入れます。 ()。
- regex.finditer(string[, pos[, endpos]])
- finditer()関数と同様に、コンパイルされたパターンを使用しますが、 searchのように検索領域を制限するオプションの pos および endpos パラメーターも受け入れます。 ()。
- regex.sub(repl, string, count=0)
- コンパイルされたパターンを使用して、 sub()関数と同じです。
- regex.subn(repl, string, count=0)
- コンパイルされたパターンを使用して、 subn()関数と同じです。
- regex.flags
- 正規表現一致フラグ。 これは、 compile()に指定されたフラグ、パターン内の
(?...)
インラインフラグ、およびパターンがUnicode文字列の場合はUNICODE
などの暗黙的なフラグの組み合わせです。 。
- regex.groups
- パターン内のキャプチャグループの数。
- regex.groupindex
(?P<id>)
で定義されたシンボリックグループ名をグループ番号にマッピングする辞書。 パターンでシンボリックグループが使用されていない場合、ディクショナリは空です。
- regex.pattern
- REオブジェクトのコンパイル元のパターン文字列。
6.2.4。 オブジェクトの一致
一致オブジェクトのブール値は常にTrue
です。 match()と search()は一致がない場合にNone
を返すため、単純なif
で一致があったかどうかをテストできます。声明:
match = re.search(pattern, string)
if match:
process(match)
一致オブジェクトは、次のメソッドと属性をサポートします。
- match.expand(template)
sub()メソッドのように、テンプレート文字列 template でバックスラッシュ置換を実行して取得した文字列を返します。
\n
などのエスケープは適切な文字に変換され、数値の後方参照(\1
、\2
)および名前付きの後方参照(\g<1>
、\g<name>
) ])対応するグループの内容に置き換えられます。バージョン3.5で変更:一致しないグループは空の文字列に置き換えられます。
- match.group([group1, ...])
一致の1つ以上のサブグループを返します。 引数が1つしかない場合、結果は1つの文字列になります。 複数の引数がある場合、結果は引数ごとに1つの項目を持つタプルになります。 引数がない場合、 group1 はデフォルトでゼロになります(一致全体が返されます)。 groupN 引数がゼロの場合、対応する戻り値は一致する文字列全体です。 包括的範囲[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'
バージョン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)
一致のすべての named サブグループを含み、サブグループ名でキー設定された辞書を返します。 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 のデフォルトはゼロです(一致した部分文字列全体を意味します)。 group が存在するが、一致に寄与しなかった場合は、
-1
を返します。 一致オブジェクト m 、および一致に寄与したグループ g の場合、グループ g (m.group(g)
と同等)によって一致した部分文字列) はm.string[m.start(g):m.end(g)]
group がnull文字列と一致した場合、
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():] '[email protected]'
- match.span([group])
- 一致する m の場合、2タプル
(m.start(group), m.end(group))
を返します。 group が一致に寄与しなかった場合、これは(-1, -1)
であることに注意してください。 group のデフォルトはゼロで、一致全体です。
- match.pos
- 正規表現オブジェクトの search()または match()メソッドに渡された pos の値。 これは、REエンジンが一致を探し始めた文字列へのインデックスです。
- match.endpos
- 正規表現オブジェクトの search()または match()メソッドに渡された endpos の値。 これは、REエンジンがそれを超えない文字列へのインデックスです。
- match.lastindex
- 最後に一致したキャプチャグループの整数インデックス。一致するグループがまったくない場合は
None
。 たとえば、式(a)b
、((a)(b))
、および((ab))
は、文字列'ab'
に適用されると、lastindex == 1
になりますが、式[ X142X] は、同じ文字列に適用された場合、lastindex == 2
になります。
- match.lastgroup
- 最後に一致したキャプチャグループの名前。グループに名前がない場合、またはグループがまったく一致しなかった場合は、
None
。
- match.re
- match()または search()メソッドがこの一致インスタンスを生成した正規表現オブジェクト。
6.2.5。 正規表現の例
6.2.5.1。 ペアの確認
この例では、次のヘルパー関数を使用して、一致オブジェクトをもう少し適切に表示します。
def displaymatch(match):
if match is None:
return None
return '<Match: %r, groups=%r>' % (match.group(), match.groups())
プレーヤーの手が5文字の文字列として表され、各文字がカードを表すポーカープログラムを作成しているとします。各文字は、エースを表す「a」、キングを表す「k」、クイーンを表す「q」、ジャックを表す「j」です。 10の場合は「t」、その値のカードを表す「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"
には、同じ価値のカードが1組または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.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'
6.2.5.2。 scanf()のシミュレーション
Pythonには現在、scanf()
に相当するものはありません。 正規表現は、scanf()
形式の文字列よりも一般的に強力ですが、より冗長です。 次の表は、scanf()
形式のトークンと正規表現の間のほぼ同等のマッピングを示しています。
scanf() トークン
|
正規表現 |
---|---|
%c
|
.
|
%5c
|
.{5}
|
%d
|
[-+]?\d+
|
%e 、%E 、%f 、%g
|
\.\d+)([eE][-+]?\d+)? |
%i
|
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
次のようなscanf()
形式を使用します
%s - %d errors, %d warnings
同等の正規表現は次のようになります
(\S+) - (\d+) errors, (\d+) warnings
6.2.5.3。 search()対。 マッチ()
Pythonは、正規表現に基づいて2つの異なるプリミティブ操作を提供します。 re.match()は文字列の先頭でのみ一致をチェックし、 re.search()は一致をチェックします文字列の任意の場所(これはPerlがデフォルトで行うことです)。
例えば:
>>> re.match("c", "abcdef") # No match
>>> re.search("c", "abcdef") # Match
<_sre.SRE_Match object; span=(2, 3), match='c'>
'^'
で始まる正規表現を、 search()とともに使用して、文字列の先頭での一致を制限できます。
>>> re.match("c", "abcdef") # No match
>>> re.search("^c", "abcdef") # No match
>>> re.search("^a", "abcdef") # Match
<_sre.SRE_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
<_sre.SRE_Match object; span=(4, 5), match='X'>
6.2.5.4。 電話帳を作る
split()は、渡されたパターンで区切られたリストに文字列を分割します。 このメソッドは、電話帳を作成する次の例に示すように、テキストデータをPythonで簡単に読み取って変更できるデータ構造に変換するために非常に役立ちます。
まず、ここに入力があります。 通常、ファイルから取得される可能性があります。ここでは、三重引用符で囲まれた文字列構文を使用しています。
>>> 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']]
:?
パターンは、姓の後のコロンと一致するため、結果リストには表示されません。 4
のmaxsplit
を使用すると、番地を通りの名前から分離できます。
>>> [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']]
6.2.5.5。 テキストの変更
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.'
6.2.5.6。 すべての副詞を見つける
findall()は、 search()のように最初のパターンだけでなく、パターンの all オカレンスに一致します。 たとえば、ライターがテキスト内のすべての副詞を検索したい場合、次のように findall()を使用できます。
>>> text = "He was carefully disguised but captured quickly by police."
>>> re.findall(r"\w+ly", text)
['carefully', 'quickly']
6.2.5.7。 すべての副詞とその位置を見つける
一致したテキストよりもパターンのすべての一致に関する詳細情報が必要な場合は、 finditer()が、文字列の代わりに一致オブジェクトを提供するので便利です。 前の例を続けると、ライターがすべての副詞とその位置をテキストで検索したい場合、次のように finditer()を使用します。
>>> text = "He was carefully disguised but captured quickly by police."
>>> for m in re.finditer(r"\w+ly", text):
... print('%02d-%02d: %s' % (m.start(), m.end(), m.group(0)))
07-16: carefully
40-47: quickly
6.2.5.8。 生の文字列表記
生の文字列表記(r"text"
)は、正規表現を正常に保ちます。 これがないと、正規表現のすべての円記号('\'
)の前に別の円記号を付けてエスケープする必要があります。 たとえば、次の2行のコードは機能的に同じです。
>>> re.match(r"\W(.)\1\W", " ff ")
<_sre.SRE_Match object; span=(0, 4), match=' ff '>
>>> re.match("\\W(.)\\1\\W", " ff ")
<_sre.SRE_Match object; span=(0, 4), match=' ff '>
リテラルの円記号と一致させたい場合は、正規表現でエスケープする必要があります。 生の文字列表記では、これはr"\\"
を意味します。 生の文字列表記がない場合は、"\\\\"
を使用して、次のコード行を機能的に同一にする必要があります。
>>> re.match(r"\\", r"\\")
<_sre.SRE_Match object; span=(0, 1), match='\\'>
>>> re.match("\\\\", r"\\")
<_sre.SRE_Match object; span=(0, 1), match='\\'>
6.2.5.9。 トークナイザーの作成
トークンライザーまたはスキャナーは、文字列を分析して文字のグループを分類します。 これは、コンパイラーまたはインタープリターを作成する際の便利な最初のステップです。
テキストカテゴリは正規表現で指定されます。 テクニックは、それらを単一のマスター正規表現に結合し、連続する一致をループすることです。
import collections
import re
Token = collections.namedtuple('Token', ['type', 'value', 'line', 'column'])
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
- フリードル、ジェフリー。 正規表現の習得。 第3版、O'Reilly Media、2009年。 この本の第3版では、Pythonについてはまったく取り上げていませんが、第1版では、優れた正規表現パターンを詳細に記述しています。