Python - よく使うモジュール - re 正規表現操作

 クラウディア
1. 概要
2. 数字を取り出す
3. 特定の文字列に囲まれた文字列を取得する
4. クォーテーションで囲まれた文字列を取得する
5. group
6. 置換

1. 概要

 「re」が、何の略かは、まだ(2021年4月9日)知りませぬ。  正規表現を使った、文字列の検索等に使用します。  本ページは、下記のサイトを参考にさせていただきました。
re --- 正規表現操作 — Python 3.9.4 ドキュメント」
「【Python】文字列から数字だけを取り出したい場合」
「正規表現でダブルクォーテーションの間だけ取得するには? - Python学習チャンネル by PyQ」
「Pythonの正規表現マッチオブジェクトでマッチした文字列や位置を取得 | note.nkmk.me
 本家(?)のドキュメントによれば、「このモジュールは Perl に見られる正規表現マッチング操作と同様のものを提供します。」と書いてあります。

2. 数字を取り出す

 正に、文字列から、数字の部分を取得したかったのです。  参考サイトを元に

結果 =  re.sub("\\D", "", "文字列")
 とすれば、文字列内に、数字があれば、取り出せるとのこと。  下記のようなソースを書いて
import re

str = "ほげげ345もけけ"
num  = re.sub("\\D", "", str)

print(num)

 実行すると、下記の結果が得られます。
345

3. 特定の文字列に囲まれた文字列を取得する

 ウェブスクレイピングでは、ありがちな、例えば

<title>タイトル</title>
 てな行のタイトルの文字列を取り出す場合・・・。  実際、対象が「html」でなくても、ウェブスクレイピングで使用する「BeautifulSoup」(「Python - ウェブスクレイピング」)が使えそうではありますが・・・。  ここでは、単純に文字列として考慮するならば、つまりタグに限ったことでなく、特定の文字列にかこまれるという意味で

result = re.findall('<title>(.*)</title>', 検索対象の文字列)
 としますと、「result[0]」にタイトルの文字列を取得することができます。  「re.findall」の結果は、「list」型なので添え字が必要です。  もし「<title>タイトル</title>」という文字列が存在しない場合があるのであれば、個数を取得する「len」を使用して

if (len(result) > 0):
 に続けて、存在する場合の処理を記述します。  「<title>」に限らず、単にタグに囲まれた文字列を検索するならば

result = re.findall('<.*>(.*)', 検索対象の文字列)
 てな書き方になります。

4. クォーテーションで囲まれた文字列を取得する

 こういう場面、わたしが「Python」を使用する中では、よく出くわすのであります。

strA = '"str1"="abc" "str2"="def"'
 てな文字列から、「"」で囲まれた文字列を全部取り出そうとして、下記のようなソースを書いても
import re

strA = '"str1"="abc" "str2"="def"'

searchA = re.findall('"(.*)"', strA)

print(searchA)

 実行すると、うまくいかない。
['str1"="abc" "str2"="def']
 最初と最後の「"」で囲まれた文字列を取り出しちゃうのであります。  でまぁ、参考サイトを元に「('"([^"]*)"[^"]*"([^"]*)"'」で検索すると
import re

strA = '"str1"="abc" "str2"="def"'

searchA = re.findall('"([^"]*)"[^"]*"([^"]*)"', strA)

print(searchA)

 うまくいくんだな。
[('str1', 'abc'), ('str2', 'def')]
 これ実は、わたし、仕組みを完全には理解していない。  思わぬ副作用で、「=」で結んだ文字列同士をそれはそれで、ひとかたまりにとらえています。  まぁ、実は使う上で、都合がよかったんですけど。  「'」で囲まれた文字列を検索するのであれば、「"」と「’」を入れ替えればいいのであって
import re

strB = "'str2'='ghi', 'str3'='jkl'"

searchB = re.findall("'([^']*)'[^']*'([^']*)'", strB)

print(searchB)

 てなソースを書いて、実行するとうまくいきます。
[('str2', 'ghi'), ('str3', 'jkl')]

5. group

 これも、うまく説明できないのですが・・・。  「re.search」でえられた結果の文字列を取得するには、「group」というものを使用します。  詳細は、参考サイトを読んでください。  本サイトを、「Laravel」へ移行する過程で

<a href="./02.html"><dt>タイトル</dt></a>
 てな文字列を下記のように変更する必要が生じたのです。

<a href="<?php $server->putRelate('./02.html'); ?>"><dt>タイトル</dt></a>
 まぁ、詳細な情報は、勘弁してくだされ。  で、コンテンツファイルを読み込んで、変更するツールを作ったわけです。
import re

line = '<a href="./02.html"><dt>基本操作</dt></a>'

print(line)

m = re.search('"(.*?)"', line)

print(m.group())

line = line.replace(m.group(), '"<?php $server->putRelate(' + m.group().replace('"', "'") + '); ?>"')

print(line)

 てなソースを書いて、実行すると下記のように出力されます。
<a href="./02.html"><dt>基本操作</dt></a>
"./02.html"
<a href="<?php $server->putRelate('./02.html'); ?>"><dt>基本操作</dt></a>

6. 置換


re.sub(正規表現, 置換後の文字列, 対象とする文字列)
 で、文字列を置換することができます。

import re

text = '''
 これは、半角スペース や 全角スペース、改行のはいった文字列から
 ホワイトスペースを除いたらどうなるかっちゅうテストです。
'''
print(text)
print(re.sub('\s+', '', text))
 てなソースを書いて、実行すると、下記の結果が得られます。

 これは、半角スペース や 全角スペース、改行のはいった文字列から
ホワイトスペースを除いたらどうなるかっちゅうテストです。

これは、半角スペースや全角スペース、改行のはいった文字列からホワイトスペースを除いたらどうなるかっちゅうテストです 。
ハイスピードプランJETBOYU-NEXT