| Lingua-AIN-Romanize documentation | Contained in the Lingua-AIN-Romanize distribution. |
Lingua::AIN::Romanize - アイヌ語のローマ字表記とカタカナ表記を相互変換するモジュール
use Lingua::AIN::Romanize;
my $kana = ain_roman2kana('aynu itak');
# アイヌ イタㇰ
my $kana = ain_roman2kana('aynu itak',{ hankaku => 1 });
# アイヌ イタク
my $roman = ain_kana2roman('アイヌ イタㇰ');
# aynu itak
my $roman = ain_kana2roman('アイヌ イタク');
# aynu itak
Lingua::AIN::Romanizeはアイヌ語のローマ字表記とカタカナ表記を相互変換する モジュールです。
UTF-8での変換を行い、Unicode3.2で定義された小文字カナを利用した変換を行い ますが、ローマ字→カナ変換はオプションで半角カナへの変換を選択することも できます。 ト゚(tu)、セ゚(ce)等の半濁音付表記については、開発者が初学者過ぎ、同じローマ 字表記が割り当てられているトゥ(tu)やチェ(ce)の別表記なのか違うものなのか、 という判断がつかなかったため、対応していません。 が、正確な情報が判れば対応可能ですので、情報をお寄せいただければ幸いです。
ベースとなっている変換ロジックはkumanesirさんの公開されている変換ロジック http://sapporo.cool.ne.jp/kumanesir/kanahenkan.htmをベースに、CDエクス プレス・アイヌ語での事例等も参考に行いました。
できる限り相互変換がラウンドトリップするように心がけましたが、やはりカナ→ ローマ字変換側で、
1.母音+イ、ウがi、uとなるケース(イヤイライケレ → ○iyairaykere ×iyayraykere) 2.人称接辞の分離(エイワンケ → ○e=iwanke ×eiwanke) 3.撥音がtとなるケース(サッケ → ○satke ×sakke)
のようなものには、基本対応できていません。
このうち、1.については、主要語であるイヤイライケレ(ありがとう)がいきなり変換 できないのではイマイチなので、事例集を内部に持つ形での対応を一応行っています。 ですので、母音+イ、ウがi、uとなるケースをサンプルとして頂戴できれば、対応は可能 です。
また、1.~3.いずれも、ロジック的な変換規則でよい案をお持ちの方がおられましたら、 教えていただければ対応いたします。 100%の対応は、ヤイライケ→yayrayke(自殺する)yairayke(感謝する)のように不可能なのは 判っていますが、少しでもよくしていきたいと考えています。 作者はプログラムはそれなりですがアイヌ語は初学者ですので、ベテランの方の支援をいた だければ幸いです。
ローマ字表記をカナ表記に変換します。 第二引数にハッシュリファレンスでオプションを取りますが、hankakuオプションを1にすると、 Unicode3.2での定義文字の代わりに半角カナを用いて変換します。
カナ表記をローマ字表記に変換します。
モジュールのロード時に、:setregexタグを指定すると、本関数と%Ain_Roman2Kana、%Ain_Kana2Roman、 @Ain_VplusiuCaseの3変数がエクスポートされます。 これらを使い、独自の変換テーブルを定義できますが、上級利用法なのでソースコードを読んで理解できる 方のみ使っていただければ幸いです。
OHTSUKA Ko-hei <nene@kokogiko.net>
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Lingua-AIN-Romanize documentation | Contained in the Lingua-AIN-Romanize distribution. |
package Lingua::AIN::Romanize; use strict; use warnings; use Carp; use version; our $VERSION = qv('0.0.2'); use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS); use Exporter; @ISA = qw(Exporter); @EXPORT = qw(ain_kana2roman ain_roman2kana); @EXPORT_OK = qw(ain_setregex %Ain_Roman2Kana %Ain_Kana2Roman @Ain_VplusiuCase); %EXPORT_TAGS = (setregex => [qw(ain_kana2roman ain_roman2kana ain_setregex %Ain_Roman2Kana %Ain_Kana2Roman @Ain_VplusiuCase)]); use Lingua::JA::Kana; use utf8; # æ¯é³ our $Re_Vowels = $Lingua::JA::Kana::Re_Vowels; # åé³ our $Re_Consonants = qr/[ptksmnwyrhc]/i; # æ¥é³ç¨ our $Re_Consonants_t = qr/[ptkcs]/i; ################################# # ãã¼ãå -> ã«ãé¢é£ # ãã¼ãåâã«ã our %Ain_Roman2Kana = ( %Lingua::JA::Kana::Romaji2Kata, qw( ca ã㣠ci ã cu ã㥠ce ãã§ co ãã§ wo ã¦ã© wu 㦠yi 㤠ya 㤠'a 㢠'i 㤠'u 㦠'e 㨠'o 㪠), ); our $Re_Roman2Kata = qr/(?:[aeiou]|s(?:[aeiou]|h[aiou]|y[aou])|d(?:[eiou]|h[aeiou]|y?a)|t(?:[aeio]|y[aeou]|s?u)|x(?:[aeio]|y[aou]|t?u)|c(?:[aeiou]|h[aeiou])|b(?:[aeiou]|y[aou])|h(?:[aeiou]|y[aou])|k(?:[aeiou]|y[aou])|p(?:[aeiou]|y[aou])|'[aeiou]|f[aeiou]|g[aeiou]|l[aeiou]|m[aeiou]|n[aeiou]|r[aeiou]|v[aeiou]|w[aeiou]|y[aeiou]|z[aeiou]|j[aiou])/i; # éé³ç¯r our $Re_R_Close = qr/($Re_Vowels)r(?!$Re_Vowels)/i; our %R_Close; $R_Close{hankaku} = {qw( a ï¾ i ï¾ u ï¾ e ï¾ o ï¾ )}; $R_Close{unicode} = {qw( a ã» i ã¼ u ã½ e ã¾ o ã¿ )}; # éé³ç¯h(樺太æ¹è¨) our $Re_H_Close = qr/($Re_Vowels)h(?!$Re_Vowels)/i; our %H_Close; $H_Close{hankaku} = {qw( a ï¾ i ï¾ u ï¾ e ï¾ o ï¾ )}; $H_Close{unicode} = {qw( a ãµ i ã¶ u ã· e 㸠o ã¹ )}; # é·é³å(樺太æ¹è¨) our $Re_Long = qr/($Re_Vowels)\1/i; # ãã®ä»ã®éé³ç¯ our $Re_O_Close = qr/(([ptkwysn])(?!$Re_Vowels|\2)|m(?!$Re_Vowels|[mp]))/i; our %O_Close; $O_Close{hankaku} = {qw( p ï¾ï¾ t ã k ク w 㦠y 㤠s ï½¼ m ï¾ n ã³ )}; $O_Close{unicode} = {qw( p ã·ã t ã k ã° w 㦠y 㤠s ã± m 㺠n ã³ )}; sub ain_roman2kana { my $str = shift; my $opt = shift || {}; my $code = $opt->{hankaku} ? 'hankaku' : 'unicode'; my $kara = $opt->{karafuto} || 0; # 人称ã®åºåãã®=ãåé¤ $str =~ s/[=ï¼]//msxgi; # réé³ç¯ãç½®ãæãã my $R_Close = $R_Close{$code}; $str =~ s{ $Re_R_Close }{ $1 . $R_Close->{$1}; }msxgei; # héé³ç¯ãç½®ãæãã(樺太æ¹è¨) my $H_Close = $H_Close{$code}; $str =~ s{ $Re_H_Close }{ $1 . $H_Close->{$1}; }msxgei; # é·é³å(樺太æ¹è¨) if ( $kara ) { $str =~ s{ $Re_Long }{ $1 . 'ã¼'; }msxgei; } # ãã®ä»ã®éé³ç¯ my $O_Close = $O_Close{$code}; $str =~ s{ $Re_O_Close }{ $O_Close->{$1}; }msxgei; local %Lingua::JA::Kana::Romaji2Kata = %Ain_Roman2Kana; local $Lingua::JA::Kana::Re_Romaji2Kata = $Re_Roman2Kata; local $Lingua::JA::Kana::Re_Consonants = $Re_Consonants_t; romaji2katakana( $str ); } ################################# # ã«ã -> ãã¼ãåé¢é£ # ã«ãâãã¼ãå our %Ain_Kana2Roman = ( %Lingua::JA::Kana::Kata2Hepburn, qw( 㢠'a 㤠'i 㦠'u 㨠'e 㪠'o ã㣠ca ã ci ã㥠cu ãã§ ce ãã§ co ã· si ã㥠tu ), qw( ï¾ r ï¾ r ï¾ r ï¾ r ï¾ r ã» r ã¼ r ã½ r ã¾ r ã¿ r ï¾ h ï¾ h ï¾ h ï¾ h ï¾ h ãµ h ã¶ h ã· h 㸠h ã¹ h ã·ã p ï¾ï¾ p ã t ク k ï½¼ s ï¾ m ã± s ã³ n ã° k 㺠m ), ); #our $Re_Kana2Roman = qr/(?-xism:(?:[ã¡ã¢ã£ã¥ã§ã¨ã©ãªã«ã¬ã®ã¯ã°ã±ã²ã³ã´ãµã¶ã¹ãºã»ã¼ã½ã¾ã¿ããã ããããããããããããããããããã ã¡ã¢ã£ã¤ã¥ã¦ã§ã¨ã©ã«ã¬ãã¯ã°ã±ã²ã³]|ã¦[ã¡ã£ã§ã©]?|ã[ã§ã£ã¥ã§]?|ã[ã§ã£ã¥ã§]?|ã[ã¡ã£ã§ã©]?|ã´[ã¡ã£ã§ã©]?|ã[ã£ã¥ã§]?|ã·[ã£ã¥ã§]?|ã¸[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ãª[ã£ã¥ã§]?|ã¤ã§?|ãã£?|ãã£?|ãã¥?|ãã¥?))/; our $Re_Kana2Roman = qr/(?-xism:(?:[ã¡ã¢ã£ã¥ã§ã¨ã©ãªã«ã¬ã®ã¯ã°ã±ã²ã³ã´ãµã¶ã¹ãºã»ã¼ã½ã¾ã¿ãããã ããããããããããããããããããã ã¡ã¢ã£ã¤ã¥ã¦ã§ã¨ã©ã«ã¬ãã¯ã°ã±ã²ã³ã°ã±ãµã¶ã¸ã¹ãºã»ã¼ã½ã¾ã¿ï½¸ï½¼ï¾ï¾ï¾ï¾ï¾ï¾ï¾ï¾ï¾ï¾]|ã¦[ã¡ã£ã§ã©]?|ã[ã§ã£ã¥ã§]?|ã[ã§ã£ã¥ã§]?|ã[ã¡ã£ã§ã©]?|ã´[ã¡ã£ã§ã©]?|ã[ã£ã¥ã§]?|ã·[ã£ã¥ã§]?|ã¸[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ã[ã£ã¥ã§]?|ãª[ã£ã¥ã§]?|ã¤ã§?|ãã£?|ãã£?|ãã¥?|ãã¥?|ã·ã?|ï¾ï¾?))/; ## éé³ç¯r #our $Re_R_Close_Rv = qr/[ï¾ï¾ï¾ï¾ï¾ã»ã¼ã½ã¾ã¿]/; # ## éé³ç¯h(樺太æ¹è¨) #our $Re_H_Close_Rv = qr/[ï¾ï¾ï¾ï¾ï¾ãµã¶ã·ã¸ã¹]/; # ## ãã®ä»ã®éé³ç¯ #our $Re_O_Close_Rv = qr/(ã·ã|ï¾ï¾|[ãクシï¾ã³ã°ã±ãº])/; #our %O_Close_Rv = qw( ã·ã p ï¾ï¾ p ã t ク k ï½¼ s ï¾ m # ã± s ã³ n ã° k 㺠m ); # æ¯é³+iãæ¯é³+uã«ãªãã±ã¼ã¹ç¨ our @Ain_VplusiuCase = qw( \biyairaykere\b ); # ã¨ã«ããã±ã¼ã¹ãéãã our $Re_VplusiuCase; our %Hs_VplusiuCase; &ain_setregex_vc; sub ain_kana2roman { my $str = shift; my $opt = shift || {}; my $kara = $opt->{karafuto} || 0; # # réé³ç¯ãç½®ãæãã # $str =~ s{ $Re_R_Close_Rv }{ # 'r'; # }msxgei; # # # héé³ç¯ãç½®ãæãã(樺太æ¹è¨) # $str =~ s{ $Re_H_Close_Rv }{ # 'h'; # }msxgei; # # # ãã®ä»ã®éé³ç¯ # $str =~ s{ $Re_O_Close_Rv }{ # $O_Close_Rv{$1}; # }msxgei; local %Lingua::JA::Kana::Kana2Romaji = %Ain_Kana2Roman; local $Lingua::JA::Kana::Re_Kana2Romaji = $Re_Kana2Roman; $str = kana2romaji( $str ); # æ¯é³ï¼i => y, æ¯é³ï¼u => w $str =~ s{ ($Re_Vowels)'?([iu]) }{ my $ret; if ( $1 eq $2 ) { $ret = $1.$2; } else { $ret = $1 . ( $2 eq 'i' ? 'y' : 'w' ); } $ret; }msxgei; # åé³å¾ã«ç¶ããªãæ¯é³ã®'ãåã $str =~ s{(?<!$Re_Consonants)'(?=$Re_Vowels)}{}msgxi; # æ¥é³å¦ç $str =~ s{t($Re_Consonants)}{$1$1}msgxi; # m/påã®ã³ã¯m $str =~ s{n([mp])}{m$1}msgxi; # æ¯é³+iãæ¯é³+uã«ãªãã±ã¼ã¹ç¨ $str =~ s{$Re_VplusiuCase}{$Hs_VplusiuCase{$1}}msgxei; $str; } sub ain_setregex { eval 'require Regexp::Assemble'; ## no critic croak 'ain_setregex function needs Regexp::Assemble module' if ( $@ ); $Re_Roman2Kata = do { my $ra = Regexp::Assemble->new(); $ra->add($_) for keys %Ain_Roman2Kana; my $str = $ra->re; substr( $str, 0, 8, '' ); # remove '(?-xism:' substr( $str, -1, 1, '' ); # and ')'; qr/$str/i; # and recompile with i }; $Re_Kana2Roman = do { my $ra = Regexp::Assemble->new(); $ra->add($_) for keys %Ain_Kana2Roman; $ra->re; }; &ain_setregex_vc; } sub ain_setregex_vc { $Re_VplusiuCase = ''; %Hs_VplusiuCase = (); foreach my $key ( @Ain_VplusiuCase ) { my $from = $key; my $to = $key; $from =~ s{($Re_Vowels)([iu])}{ $1 . ($2 eq 'i' ? 'y' : 'w') }ge; $Re_VplusiuCase .= $Re_VplusiuCase eq '' ? '(' : '|'; $Re_VplusiuCase .= $from; $from =~ s/\\b//g; $to =~ s/\\b//g; $Hs_VplusiuCase{$from} = $to; } $Re_VplusiuCase .= ')'; $Re_VplusiuCase = qr/$Re_VplusiuCase/i; } 1; __END__