ヘボン式ローマ字を音素(母音、子音)に分解


TL;DR

roman2phoneme_withN.sh
#!/bin/bash

# 撥音「ん」を"N"に置き換え前後にスペースを入れる
# NOTE: 母音のスペース区切りより先に変換しないとマ行が誤って「N+母音」になってしまう
sed -r "s/([nm])([^yaiueo])/ N \2 /g" |
# 母音の前後にスペースを入れる
sed -r "s/([aiueo])/ \1 /g" |
# 促音「っ」を"Q"に置き換え前後にスペースを入れる(チャ行以外)
sed -r "s/([^ \f\n\r\taiueo])(\1)/ Q \2/g" |
# 促音「っ」を"Q"に置き換えの前後にスペースを入れる(チャ行)
sed -r "s/tch/Q ch/" |
# 空白が連続する場合一つだけにする(見た目をきれいに)
sed -r "s/[ \f\n\r\t]+/ /g"

やりたいこと

単語を音素ごとに区切りたい
(音声分析で、テキスト側の処理として何かと欲しくなるんです…)

困ったこと

「漢字→かな」や「かな→ローマ字」の変換ツールはたくさんありますが、
意外と「ローマ字→音素」に変換するツールがなかなか見つかりません…

というわけで「ローマ字→音素」変換を正規表現で作ってみましょう!

(ちなみに、漢字、かな→ローマ字変換は
Variable name creation | 漢字をローマ字・英語に変換します。変数名を作成するためのツールです。

GitHub - miurahr/pykakasi: NLP: Convert Japanese Kana-kanji sentences into Kana-Roman in simple algorithm.
がおススメです。
この記事のローマ字サンプル作成でもお世話になりました。)

ヘボン式のルール

こちらのサイトを参考にしました。
ヘボン式ローマ字綴方表|東京都生活文化局

訓令式より発音に忠実なヘボン式、「sh」「ch」とかの2文字子音だけじゃなく、「ん」や「っ」にもややこしいルールがあったのね…

ソースコード

Linux版はbash, Windows版はPowershellなので、言語、ツール等のインストールは不要です。使うハードルを下げて、研究室で流行らせよう!

GitHub - Syuparn/roman2phonemes: ローマ字文字列を音素(子音、母音)ごとにスペース区切り

使い方

ヘボン式ローマ字を母音、子音ごとにスペースで区切ります。

input.txt
konnichiwa sekai
output.txt
k o n n i ch i w a s e k a i 

実行方法

Linux

中身はただのsedなので、ターミナルで一行打ち込むだけです。

$ cat input.txt | bash ./roman2phoneme.sh > output.txt

Windows

中身はただのPowerShellの -replace コマンドなので、PowerShellでコマンドを打ち込むだけで…

 > .\roman2phoneme.ps1 i.txt i2.txt                                 
.\roman2phoneme.ps1 : このシステムではスクリプトの実行が無効になっているため、
ファイル roman2phoneme.ps1 を読み込むことができません。詳細については、
...

……。(絶望)

PowerShellはセキュリティのため、デフォルトではスクリプト(ps1)ファイルの実行を禁止しています。
設定を緩めることもできるのですが、戻すのも手間なので、コマンドプロンプトから以下のように実行してください。

powershell -NoProfile -ExecutionPolicy Unrestricted -File ./roman2phoneme.ps1 input.txt output.txt

これで、一時的にPowerShellのスクリプト実行が許可されます。

(参考: Powershellを楽に実行してもらうには - Qiita)

Mac

手元に無いので未確認ですごめんなさい…
(sedがあるからLinux版が動く?)

注意:誤動作を起こすパターン

コードではなくローマ字そのものに関してですが…
以下のような単語はローマ字で区別されないため、間違った区切り結果が得られる可能性があります。

「ん」+「ア行」 or 「ナ行」

「全員」も「是認」もzeninです。
当コードはすべて「ん」+「ア行」(「全員」の方)と解釈します。

$ echo "zenin" | bash ./roman2phoneme_ignoreQ.sh 
z e n i n

「ん」+ヤ行or ニャ行

「記入」も「金融」もkinyuです。
当コードではすべて「ニャ行」(「金融」の方)と解釈します。

$ echo "kinyu" | bash ./roman2phoneme_ignoreQ.sh 
k i ny u 

選んだパターンに特に意味はありません。実装したらこうなってた

ちょっとバージョン違い

撥音「ん」をNにする

「ん」を大文字のNにすることで、ナ行の子音(orマ行の子音)と撥音を区別します。

$  echo "namba dempa" | bash ./roman2phoneme_withN.sh 
n a N b a d e N p a

促音をQにする

元のバージョンでは、促音をQで表し、それ以外の子音と区切って出力していました。

$ echo "shikkari zasshi matchi rakkyo" | bash ./roman2phoneme.sh
sh i Q k a r i z a Q sh i m a Q ch i r a Q ky o

このバージョンでは、促音も含めて子音はそのままひとかたまりで出力します。

$ echo "shikkari zasshi matchi rakkyo" | bash ./roman2phoneme_ignoreQ.sh 
sh i kk a r i z a ssh i m a tch i r a kky o

正規表現の中身

(PowerShell版、Bash版どちらも同じなので、Bash版で説明します)

ご覧の通り、正規表現を何重にも使って文字列を変換しています。

roman2phoneme.sh
#!/bin/bash

# 母音の前後にスペースを入れる
sed -r "s/([aiueo])/ \1 /g" |
# 撥音「ん」の前後にスペースを入れる
sed -r "s/([nm])([^y])/ \1 \2 /g" |
# 促音「っ」を"Q"に置き換え前後にスペースを入れる(チャ行以外)
sed -r "s/([^ \f\n\r\taiueo])(\1)/ Q \2/g" |
# 促音「っ」を"Q"に置き換えの前後にスペースを入れる(チャ行)
sed -r "s/tch/Q ch/" |
# 空白が連続する場合一つだけにする(見た目をきれいに)
sed -r "s/[ \f\n\r\t]+/ /g"

母音の前後にスペースを入れる

まずは母音と子音を区切ります。ローマ字の母音はaiueoの5文字だけなので、これらをキャプチャして前後にスペースを入れます。

$ sed -r "s/([aiueo])/ \1 /g"

撥音「ん」の前後にスペースを入れる

次に「ん」です。「ん」には母音が無いため、上の変換だけでは「ん」と別の子音がくっついたままになっています。

$ echo "genki" | sed -r "s/([aiueo])/ \1 /g"
g e nk i 

そのため、子音の先頭がnm(b,m,pの前では、「ん」は"m"になります!)の場合、スペースで区切ります。

sed -r "s/([nm])([^y])/ \1 \2 /g"

"N"に置き換える場合

マッチした文字そのまま出す代わりにNに置き換えます。

ただし、この場合置換は最初にやる必要があります

(母音のスペース区切りより先に変換しないとマ行が誤って「N+母音」になってしまう)

sed -r "s/([nm])([^yaiueo])/ N \2 /g"

促音「っ」を"Q"に置き換える

促音は、子音の先頭文字の繰り返しで表現されます。ただし、チャ行だけ例外でtchとなります。
チャ行とそれ以外両方に対応するため、正規表現を2回かませます。

# チャ行以外
sed -r "s/([^ \f\n\r\taiueo])(\1)/ Q \2/g" |
# チャ行
sed -r "s/tch/Q ch/"

連続する空白を一つだけにする

区切りのために重複してスペース追加してしまう場所があるため、スペースを一つだけに減らします。

sed -r "s/[ \f\n\r\t]+/ /g"

おわりに

ローマ字って意外と複雑なんだなあ…(小並)

「この文字列だと上手くいかないぞオイ」等ありましたらコメントで教えていただけるとありがたいです。