目次
置き換えたい単語の組み合わせが複数ある時に一発でやる方法
例えば、こんな文章があった時。
東京大学と大阪大学では社会人向けの「AI講座」を開いている。
また経済産業省は「AIプログラム技術」や課題解決を企業や学生らが教え合う「AI学校」を9月にも立ち上げる。
実務経験を積んだ人材が互いに鍛え合い、専門人材を育成する。
「AI学校」は「AIスクール」、「AIプログラム技術」は「AIスキル」、「AI講座」は「AIクラス」などマッチする単語によって別の単語に置き換えるのを、一発でやるにはどうしたらよいか?が、今回のテーマです。
方法1:置換対象が1文字の場合
最初の選択肢は「str.translate()」です。
置換対象が1文字の場合だと、見事に機能します。
例えば、半角の「A」を全角の「A」、「i」を全角の「I」、漢字の「実」を「業」に置き換えるような用途なら、以下のようにすればできます。
def trans_single(inputtext): encode_dic = {'A':'A','i':'I','実':'業'} encode_table = str.maketrans(encode_dic) return inputtext.translate(encode_table) intext = '''東京大学と大阪大学では社会人向けの「AI講座」を開いている。 また経済産業省は「AIプログラム技術」や課題解決を企業や学生らが教え合う「AI学校」を9月にも立ち上げる。 実務経験を積んだ人材が互いに鍛え合い、専門人材を育成する。 ''' print(trans_single(intext))
この結果はこんな感じ。
東京大学と大阪大学では社会人向けの「AI講座」を開いている。
また経済産業省は「AIプログラム技術」や課題解決を企業や学生らが教え合う「AI学校」を9月にも立ち上げる。
業務経験を積んだ人材が互いに鍛え合い、専門人材を育成する。
きれいに辞書通りに置き換わってます。
これで辞書を以下のように単語レベルに変更してみます。
replacements = {'AI講座':'AIクラス','AIプログラム技術':'AIスキル','AI学校':'AIスクール'}
すると、こんなエラーをはいて終了してしまいます。
string keys in translate table must be of length 1
方法2:単語の置き換えもできる方法
そこで「re.sub()」とlambda式の組合せでやってみます。
import re def trans_word2(inputtext): replacements = {'AI講座':'AIクラス','AIプログラム技術':'AIスキル','AI学校':'AIスクール'} print('({})'.format('|'.join(map(re.escape, replacements.keys())))) return re.sub('({})'.format('|'.join(map(re.escape, replacements.keys()))), lambda m: replacements[m.group()], inputtext) intext = '''東京大学と大阪大学では社会人向けの「AI講座」を開いている。 また経済産業省は「AIプログラム技術」や課題解決を企業や学生らが教え合う「AI学校」を9月にも立ち上げる。 実務経験を積んだ人材が互いに鍛え合い、専門人材を育成する。 ''' print(trans_word2(intext))
これを実行すると。
東京大学と大阪大学では社会人向けの「AIクラス」を開いている。
また経済産業省は「AIスキル」や課題解決を企業や学生らが教え合う「AIスクール」を9月にも立ち上げる。
実務経験を積んだ人材が互いに鍛え合い、専門人材を育成する。
うまく意図通りの置き換えができてます。
方法2は複雑なので補足説明
上記はうまく行くのですが、以下のように複雑な式になるので、補足しときます。
re.sub('({})'.format('|'.join(map(re.escape, replacements.keys()))), lambda m: replacements[m.group()], inputtext)
この式の中で、
'({})'.format('|'.join(map(re.escape, replacements.keys())))
の部分からです。
ここで辞書(例だとreplacements)を使って、正規表現の条件式を生成しています。
map関数は、「map(関数, 配列)」なので、re.escape関数で辞書のキーを処理して、エスケープ処理をさせてるだけで、その結果をjoinで連結してます。
前段の例で実行すると。
(AI\講\座|AI\プ\ロ\グ\ラ\ム\技\術|AI\学\校)
こんな感じの条件が生成されます。
条件が括弧()でくくられているので、結果はgroup()にはいっていくわけです。
それを。
lambda m: replacements[m.group()],
で一つずつ取り出して、その結果(置換前文字列がはいっている)をキーにして、 replacementsの値(置換後文字列)をとりだして、順番にre.sub()に置き換えさせている・・というわけです。
ではでは。