.NET開発者のためのブログメディア
Pythonでの正規表現検索の方法とは?str型文字列やマッチオブジェクト等について解説
- SE
- やや複雑ですが、実務でよく使われるオブジェクトなんですね。
- PM
- そうですね。Pythonではよく利用されます。目的のはっきりしたプログラムを書くことができますので、しっかりマスターしたいですね。
目次
Pythonと正規表現
プログラミング言語Pythonではreモジュールを用いて正規表現検索・置換処理を利用できます。
検索パターンおよび検索される文字列には、Unicode文字列(str型)や8ビット文字列(bytes型)が使えますがstr型とbytes型を混在させることはできません。同様に、置換時の置換文字列は検索パターンと検索文字列の両方と同じ型でなければなりません。
なお、サードパーティのregexモジュールというものもありますが、ここでは標準ライブラリのreモジュールとWindowsのPython3.9.1(Python3)を用いて解説します。
Pythonでの文字列型変数
Pythonにおいて文字列型は2種類あります。ひとつはUnicode文字列を格納するstr型、もうひとつはASCII文字列(8ビット長文字列)を格納するbytes型です。
str型は普通に文字列リテラルとして定義できますが、bytes型に全角文字(8ビットを超える文字)を含める場合にはエスケープシーケンスを用いて定義する必要があります。
bytes型で全角文字の’あいう’という文字列を定義する場合、文字コードUTF-8で表現するとそれぞれ E38182、E38184、E38186 となりますので以下のようになります。
1
|
b'\xe3\x81\x82\xe3\x81\x84\xe3\x81\x86'
|
Pythonで正規表現のパターンを記述するには
Pythonで正規表現のパターンを記述する場合、raw文字列というものを使用すると便利です。通常の文字列リテラルのバックスラッシュ(¥)はエスケープシーケンスとして扱われるため「¥¥」のように2つ重ねる必要があります。そうすると文字列リテラルは見づらくなりますし、入力するのも面倒です。
そのようなときに使われるのがraw文字列です。raw文字列リテラルを定義するときは、先頭に「r」を付けます。
以下にWindowsのパスを定義する例を示します。
1
2
3
|
'c:\\Path\\file' # 普通の文字列リテラル
r'c:\Path\file' # raw文字列リテラル
rb'c:\Path\file' # bytes型raw文字列リテラル
|
文字コードの異なるパターンと文字列での検索
Pythonで文字コードの異なるパターンを使って文字列検索する場合には、一旦Unicodeに変換してから検索を実行します。シフトJISコードとEUCコードの文字列リテラルの定義と文字コード変換の例を以下に示します。
1
2
3
4
5
|
sjis_str = b'\x82\xa0\x82\xa2\x82\xa4' #シフトJIS文字列 'あいう'
sjis_str.decode('sjis') # シフトJIS → UTF-8変換
euc_str = b'\xa4\xa2\xa4\xa4\xa4\x\a6' #EUC文字列 'あいう'
euc_str.decode('euc_jp') # EUC → UTF-8変換
|
Pythonでの正規表現の使い方
Pythonで正規表現検索する場合、検索パターンを前もってコンパイルしてから検索する方法と検索パターンをそのまま渡して検索する方法の2種類あります。
複数回連続して同じパターンを検索する場合には前もってコンパイルして正規表現オブジェクトを作成しておけば、コンパイル処理を1回しか行わないで済むため処理速度的に有利です。逆に1回ずつしか検索しない場合には関数を利用してもよいでしょう。
Pythonはインタプリタですので、プログラムをひとつひとつ入力・実行しながら動作確認していくことにします。
Pythonで正規表現を使うための準備
Pythonの正規表現はモジュールとして用意されていますので、使う前にreモジュールをインポートする必要があります。これは最初に1度だけ実行すればOKです。
1
|
>>> import re
|
正規表現オブジェクトを作成して検索
compile関数を使って正規表現オブジェクトを作成してからsearchメソッドで正規表現検索を実行し、マッチオブジェクト(後述)の結果を表示させてみることにしましょう。
1
2
3
4
5
6
|
>>> str = '今日はいい天気ですね。'
>>> r = re.compile('天気')
>>> m = r.search(str)
>>> m
<re.Match object; span=(5, 7), match='天気'>
|
正規表現の関数を使って検索
compile関数を使用しないで直接検索してみましょう。検索パターンも少し換えて「天気ですね」までマッチするようにしてみます。
1
2
3
4
5
|
>>> str = '今日はいい天気ですね。'
>>> m = re.search("天気[^。]*",str)
>>> m
<lre.Match object; span=(5, 10), match='天気ですね'>
|
検索開始位置を指定して検索する
今度は検索開始位置を指定して(終了位置も指定可能)検索させてみることにします。検索開始位置を指定するには正規表現オブジェクトのsearchメソッドを使います。「関数」の方は残念ながら対応していません。
検索開始位置はsearchメソッドの第2引数で指定します。最初は開始位置0(先頭)から検索させてみます。続いてマッチオブジェクトのendメソッド(後述)を用いてマッチした文字列の次の位置から検索を開始してみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
>>> str = '''今日はいい天気ですね。
... 明日もいい天気のようです。'''
>>> r = re.compile("天気[^。]*")
>>> m = r.search(str,0)
>>> m
<lre.Match object; span=(5, 10), match='天気ですね'>
>>> m.end()
10
>>> m = r.search(str,m.end())
>>> m
<re.Match object; span=(17, 24), match='天気のようです'>
|
グルーピング
正規表現にはグルーピングという機能がありますが、グルーピングした正規表現にマッチした文字列はキャプチャされますので取得することができます。取得するにはマッチオブジェクト(後述)を参照します。
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> str = '''bbc def ghi
... adc dgf gji'''
>>> r = re.compile('(a.c) (d.f) (g.i)')
>>> m = r.search(str)
>>> m.group(0)
'adc dgf gji'
>>> m.group(1)
'adc'
>>> m.group(2)
'dgf'
>>> m.group(3)
'gji'
|
マッチオブジェクト
マッチオブジェクトはsearch(match)関数またはメソッドで得られた情報を持っています。得られた情報を参照するためのメソッドを紹介します。以下のMはマッチオブジェクトを表します。
M.start(index)
グルーピングに対応したマッチ文字列の開始位置を返します。indexはグループのインデックスで省略可能です。省略したり0を指定するとマッチ文字列全体の先頭位置を返します。
M.end(index)
グルーピングに対応したマッチ文字列の終了位置を返します。indexはグループのインデックスで省略可能です。省略したり0を指定するとマッチ文字列全体の終了位置を返します。
M.group(index1[, …])
グルーピングに対応したマッチ文字列のうち、指定したインデックスに対応した文字列を返します。index?は複数個、指定可能です。省略したり0を指定するとマッチ文字列全体を(1つの文字列として)返します。
M.groups()
グルーピングに対応したマッチ文字列すべてを返します。戻り値はタプル型になります。
- SE
- 文字列の検索や置き換えができるようになりますね。
- PM
- マスターすれば、AI技術の基礎的な処理もできるようになるでしょう。
最後に
Pythonを使って正規表現検索するための説明をさせて頂きましたが如何でしたでしょうか。正規表現検索に使用できるフラグなども沢山あるので、気になった方は是非ご自身で調べてみて下さい。
また正規表現による文字列置換も使えるようになりますと強力なツールとなり得ます。正規表現による文字列検索ができるようになれば、置換処理(sub関数)もできるようになりますので是非ご活用ください。
Search キーワード検索
Popular 人気の記事
reccomended おすすめ記事
Categories 連載一覧
Tags タグ一覧
Jobs 新着案件
-
開発エンジニア/東京都品川区/【WEB面談可】/在宅ワーク
月給29万~30万円東京都品川区(大崎駅) -
遠隔テストサービス機能改修/JavaScript/東京都港区/【WEB面談可】/テレワーク
月給45万~60万円東京都港区(六本木駅) -
病院内システムの不具合対応、保守/東京都豊島区/【WEB面談可】/テレワーク
月給30万~30万円東京都豊島区(池袋駅) -
開発/JavaScript/東京都豊島区/【WEB面談可】/テレワーク
月給50万~50万円東京都豊島区(大塚駅) -
債権債務システム追加開発/東京都文京区/【WEB面談可】/在宅勤務
月給62万~67万円東京都文京区(後楽園駅)