ページへ戻る

− Links

 印刷 

Python​/正規表現 :: NJF Wiki

xpwiki:Python/正規表現

ページ内コンテンツ
  • Pythonで正規表現を使う時に全般的な注意事項
  • 置換
  • 検索
  • まとめ

Pythonで正規表現を使う時に全般的な注意事項 anchor.png[1] Edit [2]

Pythonの正規表現は微妙に他の言語と異なるところがあり、特に2.7系では文字コードの扱いで注意が必要です。

まずすべてstr型なら普通に実行されます。

import re

testStr = "あいうえお"

p = re.compile("あ")

print p.sub("か",testStr)

結果

かいうえお

次に全てunicodeでもうまくいきます。

# -*- coding: utf-8 -*-

import re

testStr = u"あいうえお"

p = re.compile(u"あ")

print p.sub(u"か",testStr)

結果

かいうえお

unicodeとstr型を一つにまとめようとするとエラーになります。

# -*- coding: utf-8 -*-
import re

testStr = u"あいうえお"

p = re.compile(u"あ")

print p.sub("か",testStr)

結果

Traceback (most recent call last):
  File "regExp.py", line 9, in <module>
    print p.sub("か",testStr)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe3 in position 0: ordinal not in range(128)

unicode型からstr型を検索したり、またはその逆をすると検索されません。

import re

testStr = "あいうえお" #str

p = re.compile(u"あ")  #unicode

print p.sub("か",testStr)

結果

あいうえお

これはエラーにはならないので、結構見つけにくいバグになることがあります。 かならず同じ型でそろえるようにしましょう。 日本語があるならunicodeにそろえるのがおすすめです。

また正規表現検索のメソッドは基本的にre.compleでオブジェクトを作るのと、reからメソッドを呼び出す方法と二つのやり方で実行できます。

import re

testStr = u"あいうえお"

p = re.compile(u"あ")

print p.sub(u"か",testStr)

print re.sub(u"あ", u"か", testStr)

結果

かいうえお
かいうえお

検索パターンを何度も使い回すなら、コンパイルした方がよいでしょう。 パターンも動的に変えるなら、reから呼び出すと便利です。

以下では正規表現の基本的な書式は既知のものとし、pythonでの使い方を中心に解説します。

Page Top

置換 anchor.png[3] Edit [4]

置換はすでに上の説明で使った、subとsubnがあります。 subは単純な置換、subnは置換した数とのタプルを返します。

# -*- coding: utf-8 -*-

import re

testStr = u"あいあいうえお"

p = re.compile(u"あ")

print p.sub(u"か",testStr)

for n in p.subn( u"か", testStr):
    print n

結果

かいかいうえお
かいかいうえお
2

()でのグループ化、それを参照するのにも対応。

# -*- coding: utf-8 -*-

import re

testStr = u"あいあいうえお"

p = re.compile(u"(.)あ")

print p.sub(u'\\1か',testStr)

結果

あいかいうえお

上の例では「あ」の前に文字のあるときだけ、その「あ」を「か」に変更しています。ここでもし「\\1」がないと、2文字が「か」になるため、結果は「あかいうえお」となり、「い」が消えてしまいます。グループが複数あれば「\\2」「\\3」などとして参照できます。

Page Top

検索 anchor.png[5] Edit [6]

pythonの正規表現検索は以下の物があります

メソッド特長
match文字列先頭のみにマッチする。なければNoneを返す。
searchマッチした場所を返す。なければNoneを返す。
findallマッチした部分をリストにして返す。
finditerマッチした部分のMatchオブジェクトのイテレーターを返す。

matchとsearchは特に文字列の存在チェックなどによく使います。

# -*- coding: utf-8 -*-

import re

testStr = u"あいうえお"

checkStr = u"うえお"

if re.search(checkStr, testStr):
    print "searched"
    
if re.match(checkStr, testStr):
    print "matched"

結果

searched

この例では正規表現がないので、「in」を使ってもよいです。 「match」は先頭のみにヒットするので、「search」に比べると使用頻度は少なめです。

ヒットした文字列が必要なら「findall」を使います。 より詳しい情報が必要なら開始、終了位置などが入ったMatchオブジェクトを返す「finditer」を使います。

# -*- coding: utf-8 -*-

import re

testStr = u"にわにはにわにわとりがいる"

checkStr = u"にわ"

resultList = re.findall(checkStr,testStr)

for r in resultList:
    print r

print 

for r in re.finditer(checkStr,testStr):
    print r.group() #検索文字列
    print r.start(),r.end() #開始位置、終了位置
    print r.span() #開始、終了位置のタプル

結果

にわ
にわ
にわ

にわ
0 2
(0, 2)
にわ
4 6
(4, 6)
にわ
6 8
(6, 8)
Page Top

まとめ anchor.png[7] Edit [8]

検索、置換ともにもう少し機能がありますが、よく使うのはこのあたりです。 特に文字コードの扱い、searchとmatchの違いなどではまりやすいので注意が必要です。 正規表現の文法は他の言語などで使われるものと同様です。


Last-modified: 2017-08-11 (金) 15:32:46 (JST) (2442d) by njf