tokenize_by_script 這個函式
作者:gugod 發佈於: #code #perl一陣子之前隨意把一些處理中文的字串處理函式打包成 Text::Util::Chinese 模組釋出了。其中包含一個函式名為 tokenize_by_script
。
這個函式的主要功用是將一個字串依每個字符之 Script 屬性值切開成多個單位。例如這個混合多語言的字串,「池袋這個地名寫成日語假名為イケブクロ,英譯為Ikebukuro,但如果向人問路時唸成ㄔˊㄉㄞˋ反而沒人聽得懂。」,會被切開成這 13 段:
- 池袋這個地名寫成日語假名為
- イケブクロ
- ,
- 英譯為
- Ikebukuro
- ,
- 但如果向人問路時唸成
- ㄔ
- ˊ
- ㄉㄞ
- ˋ
- 反而沒人聽得懂
- 。
會需要這種函式,主要是因爲在處理多語言混合文字時,通常同一種書寫系統(Script)的處理方式是類似的。只要是拉丁文字,無論寫的是英文或是荷蘭文,大致上的初步處理就是先依照空白切開,只要是漢字,無論是日文或是中文,多半需要依詞典分詞或是做 bigram。
就算是書寫中文,注音符號的處理規則也與漢字不同,多半不必做 bigram。片假名與平假名這兩種表音符號也是。
這個函式全文如下(Perl 版):
use Unicode::UCD qw(charscript);
sub tokenize_by_script {
my ($str) = @_;
my @tokens;
my @chars = grep { defined($_) } split "", $str;
return () unless @chars;
my $t = shift(@chars);
my $s = charscript(ord($t));
while(my $char = shift @chars) {
my $_s = charscript(ord($char));
if ($_s eq $s) {
$t .= $char;
}
else {
push @tokens, $t;
$s = $_s;
$t = $char;
}
}
push @tokens, $t;
return grep { ! /\A\s*\z/u } @tokens;
}
每個字符的屬性之取得是以 charscript
這個來自 Unicode::UCD
模組的函式來完成。這函式是 Unicode Character Database 這個資料集的介面之一。