4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Pythonの正規表現による置換でマッチした文字列に応じて置換する文字列を変化させる

Last updated at Posted at 2017-07-03

環境

Python 3.5.2で検証

使用場面

正規表現による置換を行うとき,マッチした文字列に応じて置換する文字列を変化させたい場合

例として,以下のようなことができます.

  • 文字列中にある数字に対して,何かしらの演算をした結果に置換したい
    "abcd1234efg" -> "abcd2468efg" (数字を2倍)
  • 文字列中にある数字を漢数字に置換したい
    "abcd1234efg" -> "abcd千二百三十四efg"

(上の例以外にも,より複雑な処理をさせることが可能だと思います)

方法

通常の正規表現による置換で使用するre.sub()と,マッチした文字列に施したい処理を実装した関数を用います.

具体的には,re.sub(パターン, 関数, 検索する文字列)とします.
上記で呼び出す関数の引数を仮にmatchobjとすると,関数内でmatchobj.group(0)とすることでパターンにマッチした文字列を利用できます.

def replace(matchobj):
    s = matchobj.group(0)
    # 行いたい処理

re.sub(`hoge`, replace, "sampletext")

実装例

下の例では,数字を漢数字に変換する関数toKansuji()と,5%の消費税を8%に変更する関数fixTax()を用意し,re.sub()内でマッチした数字に対して上記の関数を適用した結果に置換しています.

コード

sample.py
import re

def toKansuji(matchobj):
    a = ["一", "万", "億", "兆", "京"]
    b = ["一", "十", "百", "千"]
    c = ("", "一", "二", "三", "四", "五", "六", "七", "八", "九")
    s = matchobj.group(0)
    l = [int(i) for i in s]
    result = ""
    length = len(l)
    for i in range(length):
        n = l[length-1-i]
        if i%4 == 0 and i//4 > 0: 
            az = 1
            for j in range(4):
                if l[length-1-i-j] != 0: az = 0
            if az == 0: result = a[i//4] + result
        if n != 0:
            if i%4 != 0:
                result = b[i%4] + result
                if n != 1: result = c[n] + result
            else:
                result = c[n] + result
    return result

def fixTax(matchobj):
    d = int(matchobj.group(0))
    d = int(d / 1.05 * 1.08)
    return str(d)

if __name__ == '__main__':
    s1 = "税込315円"
    print("消費税5%:", s1)
    print("消費税8%:", re.sub('\d+', fixTax, s1))

    s2 = "IPv4は4294967296個"
    print("数字  :", s2)
    print("漢数字:", re.sub('\d{2,}', toKansuji, s2))

実行結果

消費税5%: 税込315円
消費税8%: 税込324円
数字  : IPv4は4294967296個
漢数字: IPv4は四十二億九千四百九十六万七千二百九十六個

上2行は消費税を5%から8%に,下2行は数字を漢数字に置換しています.

その他

パターンにおいて()を用いてグループ化すると,関数内でmatchobj.group(n)とすることでそのグループ内でマッチした文字列を利用することもできます.

(また,今回用意した関数はどちらも動作確認程度に用意したものなので,あらゆる入力に対して正確な値を返さないかもしれません)

参考

https://docs.python.jp/3/library/re.html

4
5
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
5

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?