Pythonで日本語間の空白を消す

先日投稿した内容で、日本語間に不要な空白が混じってしまうことに気付いてしまったので、下記のようなコードを考えました。

コード

import re
#str ="田中 太郎 is Japanese boy.という 例文があります。"

#result = re.sub(r'[a-z]+', "0", str)
result = re.sub('([あ-んア-ン一-鿐])\s+((?=[あ-んア-ン一-鿐]))',r'\1\2', str)

print(str)
print(result)
田中 太郎 is Japanese boy.という 例文があります。
田中太郎 is Japanese boy.という例文があります。

という感じで一応の対策はできた気がする。

と思って色々試していたら、おかしな出力の部分がありました。

ウィキペディア へようこそ ウィキペディアは 誰でも編集できる フリー 百科事典 です。
ウィキペディアへようこそウィキペディアは誰でも編集できるフリー 百科事典です。

「フリー百科事典」が「フリー 百科事典」となって、「フリー」と「百科事典」の間に空白が入ってしまっています。 調べましたが、要するに長音が上記の正規表現の中に入っていなかったので、「ー百」の部分を見たときにマッチしていないようでした(一(いち)とー(長音)が区別つきにくい)。ですので、素直に正規表現のパターンに長音を追加します。

result = re.sub('([あ-んア-ン一-鿐ー])\s+((?=[あ-んア-ン一-鿐ー]))',r'\1\2', str)
ウィキペディア へようこそ ウィキペディアは 誰でも編集できる フリー 百科事典 です。
ウィキペディアへようこそウィキペディアは誰でも編集できるフリー百科事典です。

若干の解説

  • re.sub(正規表現パターン, 置換する文字列, 置換される文字列(, 置換する回数))

re.replaceの場合はただの文字列の置換で、re.subだと正規表現を使える。第3引数はなくてもいい。

  • [あ-んア-ン一-鿐ー]

ひらがな、カタカナ、漢字、長音のどれか一文字

  • \s

空白

  • ?=

Pythonの肯定先読み。今回の場合例えば「日 本 語」というのがあって、肯定先読みを行わないパターンだった場合、「日 本 語」のうちまず「日 本」にマッチする。そして「本」は既にマッチした文字列なので「本 語」にはマッチせず、「日本 語」という置換のされ方になる。

しかし、肯定先読みを用いると「〜が後に付く○○」の○○にマッチする。今回だと「日本語が後に着く、日本語+空白」にマッチするので、「日 本 語」の「日 」にマッチして、次に「本 」にもマッチするので「日本語」という出力になる。

  • r'\1\2'

かっこで指定したマッチした1つ目2つ目を繋げる(空白を除く)

以上

これで一応解決したでしょうと思いたい。

追記

結局、またQiitaにも投稿した。

qiita.com