はじめに
まえにPythonで藤原竜也になりたいという記事を書きました。
そこで、@raityoさんから「濁点付きの文字にも濁点がついてしまいますが(「じ゛」とか)、if文でひとつひとつ指定して取り除くしかないですかね?」というコメントを頂きました。ありがとうございます。
なので、今回は濁点や半濁点がついている文字は濁点が重複しないようにしようと思います。
まあ、藤原竜也さんは濁点にも濁点がつくような素晴らしい演技をする方なのでいいかな~と思ったのですが、単純に興味で。
追記:
2018/09/12 少し修正
仕様
- 入力された文字、一文字ずつに「゛」をつける。
- ひらがなとカタカナの濁点と半濁点は、新たに加える(藤原竜也する)濁点と重複してはならない
- ただし、濁点や半濁点が入力されたら重複させる
流れ
「濁点がついている文字は濁点をつけない」ではなく、「濁点がついている文字は濁点を消して最後まとめて濁点をつける」という方法を取ります。
- 入力されたテキストを一文字ずつ調べる
- ひらがなかカタカナなら濁点や半濁点を消す
- 表示させるときに一文字ずつ全ての文字に「゛」をつける
という感じでいきたいと思います。
入力テキストの濁点と半濁点の消し方
「濁点と半濁点がついている」という限定的なふるいの掛け方は難しそうなのでやめます。
では、まずはカタカナについて考えていきます。
例えば「ザ」と「ザ」
これは読み方的には同じですが、データ的には別物です。
unicodeではザは「30B6」、
ザは「FF7B(サ)」「FF9E(゙)」の二つで構成されています。
ということは、消すためには
ひらがなとカタカナは一旦、半角カタカナにする
↓
一文字目だけ使う
これでおのずと濁点と半濁点は消えてくれますね。
ひらがなやカタカナを判定する
ひらがなとカタカナの判定は正規表現の「re」というモジュールを使います。
import re
hiragana = re.compile(r'[\u3041-\u3096]') #ひらがなの登録
katakana = re.compile(r'[\u30A0-\u30FA]') #カタカナの登録
unicodeでは
「3040」~「309F」がひらがな
「30A0」~「30FF」がカタカナとなっています。(漏れがあるけどそのまでは気にしなくていいことにする)
次はこれをもとに判断していきます。
import re
hiragana = re.compile(r'[\u3041-\u3096]') #ひらがなの登録
katakana = re.compile(r'[\u30A0-\u30FA]') #カタカナの登録
def isAllHiragana(s): #文字列全てがひらがなならTrue
for i in s:
if hiragana.search(i) is None:
return False
return True
def isAllKatakana(s): #文字列全てがカタカナならTrue
for i in s:
if katakana.search(i) is None:
return False
return True
今回は一文字ずつ判断するので繰り返し処理はいらないのですが、今後使うかな~と思って一応「全て」というような処理を書きました(使わない)
濁点と半濁点を消す(無視する)
次は濁点と半濁点を消すために、ひらがなもカタカナも、半角のカタカナに変換します。
変換には「jaconv」をimportして使います。
実際に濁点を消しているわけではなく、無視するという表現の方が正しい気がする…?
import jaconv
def RemoveHandakuon(s):
if isAllHiragana(s): #ひらがなの場合
s = jaconv.hira2hkata(s) #半角カタカナに変換
s = jaconv.h2z(s[0]) #一文字目だけを全角カタカナに戻す
s = jaconv.kata2hira(s) #ひらがなに戻す
elif isAllKatakana(s): #カタカナの場合
s = jaconv.z2h(s) #半角カタカナに変換
s = jaconv.h2z(s[0]) #一文字目だけを全角カタカナに戻す
return s
一文字ずつ判定し「゛」をつける
一文字ずつ判定していきます
def main():
tatsuyaText = list() #藤原竜也になる
char = ""
text = input("Please input a text\n")
for c in text: #一文字ずつ判定していく
if isAllKatakana(c) or isAllHiragana(c): #ひらがなかカタカナなら
char = RemoveHandakuon(c)
elif c == '゙': #半角カタカナの独立した濁点を排除
continue
else:
char = c
tatsuyaText.append(char)
これで濁点と半濁点が消えてくれました。
あとは「゛」をつけて藤原竜也になるだけです。
コードは@shiracamusさんが前回の記事のコメントで書いてくださったコード使わせていただきます。
print(*(c + '゛' for c in tatsuyaText), sep='') #一文字ずつ藤原竜也にしていく
藤原竜也になりたい
そして今回のコードがこちらです。
import re
import jaconv
hiragana = re.compile(r'[\u3041-\u3096]') #ひらがなの登録
katakana = re.compile(r'[\u30A0-\u30FA]') #カタカナの登録
def isAllHiragana(s): #文字列全てがひらがなならTrue
for i in s:
if hiragana.search(i) is None:
return False
return True
def isAllKatakana(s): #文字列全てがカタカナならTrue
for i in s:
if katakana.search(i) is None:
return False
return True
def RemoveHandakuon(s):
if isAllHiragana(s): #ひらがなの場合
s = jaconv.hira2hkata(s) #半角カタカナに変換
s = jaconv.h2z(s[0]) #一文字目だけを全角カタカナに戻す
s = jaconv.kata2hira(s) #ひらがなに戻す
elif isAllKatakana(s): #カタカナの場合
s = jaconv.z2h(s) #半角カタカナに変換
s = jaconv.h2z(s[0]) #一文字目だけを全角カタカナに戻す
return s
def main():
tatsuyaText = list() #藤原竜也になる
char = ""
text = input("Please input a text\n")
for c in text: #一文字ずつ判定していく
if isAllKatakana(c) or isAllHiragana(c): #ひらがなかカタカナなら
char = RemoveHandakuon(c)
elif c == '゙': #半角カタカナの独立した濁点を排除
continue
else:
char = c
tatsuyaText.append(char)
print(*(c + '゛' for c in tatsuyaText), sep='') #一文字ずつ藤原竜也にしていく
if __name__ == '__main__':
main()
Please Text
僕はキラなんかじゃない!!信じてくれよおおおおおお
僕゛は゛キ゛ラ゛な゛ん゛か゛し゛ゃ゛な゛い゛!゛!゛信゛し゛て゛く゛れ゛よ゛お゛お゛お゛お゛お゛お゛
無゛事゛濁゛点゛と゛半゛濁゛点゛か゛重゛複゛す゛る゛こ゛と゛な゛く゛藤゛原゛竜゛也゛に゛な゛る゛こ゛と゛か゛て゛き゛ま゛し゛た゛。゛