TL;DR
# !/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: ローマ字文字列を音素(子音、母音)ごとにスペース区切り
使い方
ヘボン式ローマ字を母音、子音ごとにスペースで区切ります。
konnichiwa sekai
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版で説明します)
ご覧の通り、正規表現を何重にも使って文字列を変換しています。
# !/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
そのため、子音の先頭がn
とm
(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"
おわりに
ローマ字って意外と複雑なんだなあ…(小並)
「この文字列だと上手くいかないぞオイ」等ありましたらコメントで教えていただけるとありがたいです。