logologo
Pythonで正規表現を使うには?使用する特殊文字を一覧で解説
thumb_pythonre_01
Pythonで正規表現を使うには?使用する特殊文字を一覧で解説
アンドエンジニア編集部
2024.07.31
この記事でわかること
Pythonで正規表現を使うには、組み込みモジュールのreを用います
膨大なデータから任意の文字を抽出するには、正規表現を用いて必要な文字を示します
提供される関数が多く、データの抽出や分割、置換など多様な使い方が可能です

Pythonで正規表現を使うには

img_pythonre_01

正規表現とは、文字列のパターンマッチングを行うための表記方法を示すものです。正規表現は英語で「Regular Expressions」と呼び、Pythonで使用するには組み込みモジュールのreを用います。reモジュールは、 ”import re” でライブラリを読み込み、必要な関数を使用することができます。

【参考】:Python Docs: 正規表現 HOWTO 【参考】:Python Docs: re --- 正規表現操作

Pythonのモジュールとは?概要と使い方をわかりやすく解説!
便利なPythonモジュールの一覧!おすすめ外部ライブラリも紹介

正規表現の役割とメリット

私たちの扱うデータには、単語や文字、文章など多くの種類があり、記号なども含めると膨大です。これらを扱うために、プログラミング言語では文字と文字列で表し、Pythonでは文字の集合体を文字列で表します。

正規表現は、このような膨大な文字列から任意の文字を抽出するために用いる1つの表記形式を指します。文字列の集合体から、決められたパターンのデータが含まれているか確認するために用います。抽出が必要な文字列すべてを記載することなく、パターンとして与えることで、求める文字列を簡単に探せます。

正規表現を必要とするケース

データの処理で特定パターンに合致するパターンマッチングができると、効率的にデータの抽出ができます。

例えばウェブページで見られる、 ”For more information, please call 0120-345-6789” のような文章があり、電話番号の数字だけ取り出したい場合、どうすればいいのでしょうか。このような場合に正規表現を用いると、簡単に数字を取り出すことができます。

正規表現の表記法

img_pythonre_02

ここでは、先の電話番号を取り出すケースのような、文字列から数字だけを取り出す場合を考えてみます。この場合、正規表現で任意の数字を表すには、 ”\d” あるいは ”[0-9]” が用意されています。

このような正規表現は文字の種類ごとに定義されており、波括弧(”{ }”)、角括弧(””)、丸括弧(”( )”)や ”^$.?” などの特殊な文字を用いて表記されます。Pythonの正規表現で用いる記法は、大まかに特殊文字と特殊シーケンスに分けられます。詳しくは、以降で解説していきます。

【参考】:Python Docs: 正規表現 HOWTO 【参考】:Python Docs: re --- 正規表現操作

特殊文字の概要と一覧

特殊文字は、それ自身が対象とする文字列に含まれているものではなく、文字列を代わりに表現するための置換文字を表します。一覧で表すと次のように分類付けられており、用途に応じて記述が可能です。

ここでは、使用例も合わせて掲載しておきます。

image
 【表】:特殊文字の正規表現と使用例

特殊シーケンスの概要と一覧

特殊シーケンスは、エスケープシーケンスと同様に特殊文字バックスラッシュ ”” で表す正規表現です。文字リテラルと同様に、バックスラッシュに続けてエスケープが必要な文字を指定します。バックスラッシュのみで正規表現が構成されるわけではなく、続く文字指定によってパターンを切り替えます。

具体的には次のようなものがあります。

image
 【表】:特殊シーケンスの正規表現と使用例

Pythonで正規表現を使ってみる

img_pythonre_05

Pythonでは、組み込みモジュールを用いて正規表現を扱います。正規表現で任意の数字を表すには、 ”\d” あるいは ”[0-9]” を使用します。ここでは、文字列が数字なのかパターンマッチングを行います。

例えば、文字列 "1234567890ABC" から先頭の数字のみを取り込む場合は、 ”^\d+” と記述します。 ”^” は先頭を意味し、 ”\d” は数字、数字の後の ”+” は1回以上の繰り返しです。なお、Pythonの文字列は、シングルクォーテーション(’)とダブルクォーテーション(”)で違いはありません。

パターンマッチングを実際に行うには、reモジュールの関数を用います。ここでは、re.match()関数を用いて以下のように求めることができます。

import re
textstr="1234567890ABC"
pattern="^\d+"

ret = re.match(pattern, textstr)
if ret: 
  print(ret)  # “<re.Match object; span=(0, 10), match='1234567890'>”が表示され、10文字目までマッチしたことがわかります
  print(ret.group())  # “1234567890”が表示されます

【参考】:Python Docs: 正規表現 HOWTO 【参考】:Python Docs: re --- 正規表現操作

正規表現のパターンをオブジェクトに置き換える

正規表現を実行時に都度用いると、複雑なパターンでは処理時間がかかるデメリットがあります。処理を効率的に行うため、Pythonでは事前にパターンオブジェクトにコンパイルが可能です。ここでは、さきほど数字を取り込むために用いた正規表現である 、 ”^\d+” を事前コンパイルしてみます。

コンパイルはre.compile()を用い、match()オブジェクトでパターンマッチングの結果を得ます。具体的には、次のように記述します。

import re
textstr="1234567890ABC"
pattern="^\d+"

p = re.compile(pattern)
ret = p.match(textstr)
if ret: 
  print(ret)  # “<re.Match object; span=(0, 10), match='1234567890'>”が表示され、10文字目までマッチしたことがわかります
  print(ret.group())  # “1234567890”が表示されます

この方法は、後述するre.search()でも同様の使い方が可能です。

パターンマッチングの関数の違い

パターンマッチングの関数では、先に紹介したre.match()関数に加えて、re.search()関数が提供されています。いずれもパターンマッチングに利用しますが、re.match()関数は文字列の先頭からパターンを探すのに対して、re.search()関数はマッチする最初の場所を文字列全体から探す点に違いがあります。

プログラミングの関数とは?役に立たない?学び方と実務で役立つスキル

re.match()関数の使い方

re.match()関数は、reモジュールの代表的な関数でパターンマッチングに用います。

re.match()の戻り値は、matchオブジェクトで文字列の先頭から探します。マッチしない場合はNoneを返します。

matchオブジェクトのgroup()メソッドは、正規表現にマッチした文字列を返します。start()は開始位置、end()は終了位置、span()は開始既知と終了位置をタプルで返します。

ここでは、冒頭で示した "For more information, please call 0120-345-6789" から電話番号を取り込むサンプルを示します。文頭の英字はスキップし、数字のみをグループインデックス1に格納しています。なお、グループの考え方はここでは省略し、後半で解説します。

import re
textstr= "For more information, please call 0120-345-6789"
pattern=”\D+(\d{2,4}-\d{1,4}-\d{4})”

ret = re.match(pattern, textstr)
if ret: 
  print(ret) # "<re.Match object; span=(0, 47), match='For more information, please call 0120-345-6789'>"が表示されます
  print(ret.group(1)) # 0120-345-6789が表示されます
  print(ret.start(1)) # 34が表示されます
  print(ret.end(1))   # 47が表示されます
  print(ret.span(1))  # (34, 47)が表示されます

この例では、ret.group()は該当する英数字を含む文字列全体、ret.group(1)は数字部分だけが格納されています。ret.group(1)では、行頭の非数字の文字は ”\D+” で取り除き、電話番号の部分は、 ”(\d{2,4}-\d{1,4}-\d{4})” で表しています。

電話番号はハイフン付きの場合、固定電話やフリーダイヤル、携帯番号などで文字数に違いがあります。この例では、 ”03” などで始まる市外局番や ”0120-345-6789” 、携帯電話の ”090-1234-5678” でもマッチするように、最初の数字は2~4字、2番目の数字は1~4字、3番目は4字としています。

【参考】:Python Docs: re --- 正規表現操作 Pattern..match()

re.search()関数の使い方

先ほどのre.match()を使って電話番号を取り出す例では、行頭の非数字の文字を ”\D+” で除外する必要がありました。ここで紹介するre.search()関数では、マッチする場所を全体から探しますので、 ”\D+” を付けずに探せます。その結果、簡単な指定だけで求める文字列を探すことが可能です。

import re
textstr= "For more information, please call 0120-345-6789"
pattern=”(\d{2,4}-\d{1,4}-\d{4})” # ”\D+”を付けずに探すことができます

ret = re.search(pattern, textstr)
if ret: 
  print(ret) # "<re.Match object; span=(0, 47), match='For more information, please call 0120-345-6789'>"が表示されます
  print(ret.group()) # 0120-345-6789が表示されます
  print(ret.start()) # 34が表示されます
  print(ret.end())   # 47が表示されます
  print(ret.span())  # (34, 47)が表示されます

これらのことから、文字列の先頭から探す場合はre.match()関数を使い、文字列全体から探す場合はre.search()関数を使うと効率的に使用できることがわかるでしょう。

【参考】:Python Docs: re --- 正規表現操作 Pattern.search()

正規表現をグルーピングして使用する

正規表現の丸括弧 ”( )” は、グループの開始と終了を意味します。この組み合わせを工夫してさらに細かくグルーピング(グループ化)も可能です。グループ化することによって、それぞれの文字列をグループ毎に効率的に扱うことが可能になります。

ここでは、先ほどの電話番号を探す正規表現の ”(\d{2,4}-\d{1,4}-\d{4})” を、次のように "(\d{2,4})-(\d{1,4})-(\d{4})" と変更し、ハイフンを除いた3つのグループを作成してみます。

import re
textstr= "For more information, please call 0120-345-6789"
pattern=”(\d{2,4})-(\d{1,4})-(\d{4})” # ”ハイフンを除いた3つのグループに分けます

ret = re.search(pattern, textstr)
if ret: 
  print(ret) # "<re.Match object; span=(0, 47), match='For more information, please call 0120-345-6789'>"が表示されます
  print(ret.group())   # 0120-345-6789が表示されます
  print(ret.group(1))  # 0120が表示されます
  print(ret.group(2))  # 345が表示されます
  print(ret.group(3))  # 6789が表示されます

これによって、re.search()が返すオブジェクトgroup()にgroup(1)、group(2)、group(3)の値が格納されます。それぞれハイフンで分割した数字が格納されています。start()、end()、span()にもそれぞれのグループに応じたインデックスに値が格納されています。

グルーピングによって簡単に電話番号の市外局番を統合管理したり、用途別に仕分けしたりすることが可能です。

Pythonの正規表現は活用の幅が広い

img_pythonre_06

これまでに、正規表現を扱うre.match()やre.search()関数を取り上げました。この他にも、re.fullmatch()関数は、文字列全体のパターンマッチングの結果を返し、re.split()関数は、指定したパターンで文字列を分画します。文字列の置換を行う関数も提供されています。

このように、Pythonの活用方法は幅広いため、基本を学んだらさらに多くの関数を活用することで、効率的なパターンマッチングが実現できるでしょう。

【入門編】Pythonの基本構文まとめ!学習方法や年収も解説
Python学習におすすめの本27選!初心者・中級者・上級者別に紹介
Pythonで開発を行う際におすすめのツールを徹底解説!
気になる人のXをフォローしよう!
公式LINE
公式YouTube
マイナビITエージェント

編集部オススメコンテンツ

Sponsored
【年収±診断】6つの質問に答えて、真の市場価値をチェック!
マイナビITエージェント
Sponsored

アンドエンジニアへの取材依頼、情報提供などはこちらから

お問い合わせ・情報提供
はじめて転職される方へ
SE・システムエンジニア(IT/通信/インターネット) 求人一覧

編集部おすすめコンテンツ

Sponsored
【年収±診断】6つの質問に答えて、真の市場価値をチェック!
マイナビITエージェント
Sponsored

アンドエンジニアへの取材依頼、情報提供などはこちらから

logologo
Powered by マイナビ AGENT