
前提・実現したいこと
ローマ字をひらがなに変換するプログラムを作成したいです。
「あ行」と「い行」のみを扱います。
(例) aki → あき ki → き
発生している問題
aki → あkい ki → kい
のように「あ行」しか正しく表示されない。「か行」は始まりの子音kがそのままで、
終わりの母音の部分が「あ行」として表示されてしまう。
該当のソースコード
PHP
1$kana = [ 2 'あ', 'い', 'う', 'え', 'お', 3 'か', 'き', 'く', 'け', 'こ', 4]; 5 6$romaji = [ 7 'a', 'i', 'u', 'e', 'o', 8 'ka', 'ki', 'ku', 'ke', 'ko', 9]; 10 11 12$str = "aki"; // あき 13 14$str = to_kana($str, $romaji, $kana); 15echo $str;
PHP
1function to_kana($str, $romaji, $kana){ 2 3 $patterns = []; 4 foreach($romaji as $value){ 5 $patterns[] = '/' . $value . '/'; 6 } 7 8 $str = preg_replace($patterns, $kana, $str); 9 return $str; 10 11}
結果
あkい
疑問
preg_replece マニュアルより
pattern および replacement のいずれもが配列の場合、 各 pattern は 対応する replacement に置換されます。
この場合、配列のインデックス番号順「a」「i」「ki」の順番で置換するので、
aki → あki → あkい
となってしまうのでしょうか?
preg_replace の挙動としては以下の認識で正しいでしょうか?
1.「aki」の「a」を置換 2.「あki」として先頭の文字からパターンを探す 3.「あ」、「k」は一致せず「i」で初めて一致し置換 4.「あkい」として先頭の文字からパターンを探す
試したこと
'aki' を 'a' と 'ki' に分割して置換するために、まず 'a', 'k', 'i' のように文字を分割して配列に入れる。
配列を回して、子音の時には次の要素と連結させる。(kだったら次のiと連結してkiにする)
これを実装してみましたが、結局「ki」と連結されても preg_replace で最初にiが置換されるので「kい」となってしまいます。
当然ですが実装後の結果は「あkい」で変化ありませんでした。
※あまり意味ないと思いますが実装後のコードも下に記載します。(汚いコードですみません。)
「ki」を「き」に置換させるためにはどうすれば良いでしょうか?
preg_replaceでは難しい場合、他の方法では可能でしょうか?
どうか教えていただけると幸いです。
###実装後のコード
PHP
1function to_kana($str, $romaji, $kana){ 2 3 $a = str_split($str); 4 5 $patterns = []; 6 foreach($romaji as $value){ 7 $patterns[] = '/' . $value . '/'; 8 } 9 10 $tmp =""; 11 12 foreach ($a as $key => $word) { 13 14 if($key != 0){ 15 $pre = $key-1; 16 $w = $a[$pre]; 17 $rep = preg_replace($patterns, $kana, $w); 18 //もし1つ前の要素が置換されていなかったら(子音だったら) 19 if($rep === $w){ 20 continue; 21 } 22 23 } 24 25 $append =""; 26 27 $replaced = preg_replace($patterns, $kana, $word); 28 //もし置換されなかったら(子音だったら) 29 if($replaced === $word){ 30 $append = $a[$key].$a[$key+1]; 31 $replaced = preg_replace($patterns, $kana, $append); 32 } 33 34 $tmp .= $replaced; 35 } 36 return $tmp; 37 38}

回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/06/01 10:34
退会済みユーザー
2018/06/01 10:42 編集
2018/06/02 09:40