我正在尋找一種方法來匹配Unicode字符串中只有完全組成的字符。如何在Perl中匹配Unicode字符串中完全組成的字符?
是[:print:]
依賴任何包含此字符類的正則表達式實現中的語言環境?例如,它是否與日文字符'あ'相匹配,因爲它不是控制字符,或者是[:print:]
總是成爲ASCII碼0x20到0x7E?
是否有任何字符類,包括Perl RE,可以用來匹配控制字符以外的任何東西?如果[:print:]
僅包含ASCII範圍內的字符,我會假設[:cntrl:]
也是。
我正在尋找一種方法來匹配Unicode字符串中只有完全組成的字符。如何在Perl中匹配Unicode字符串中完全組成的字符?
是[:print:]
依賴任何包含此字符類的正則表達式實現中的語言環境?例如,它是否與日文字符'あ'相匹配,因爲它不是控制字符,或者是[:print:]
總是成爲ASCII碼0x20到0x7E?
是否有任何字符類,包括Perl RE,可以用來匹配控制字符以外的任何東西?如果[:print:]
僅包含ASCII範圍內的字符,我會假設[:cntrl:]
也是。
echo あ| perl -nle 'BEGIN{binmode STDIN,":utf8"} print"[$_]"; print /[[:print:]]/ ? "YES" : "NO"'
雖然它會產生一個關於寬字符的警告,但大多數情況下,但是它給了你一個想法:你必須確定你正在處理一個真正的Unicode字符串(檢查utf8 :: is_utf8)。或者根本檢查perlunicode - 整個主題仍然讓我頭暈目眩。
是的,這些表達式是區域設置相關的。
您能否命名允許[:print:]尊重日語UTF-8語言環境/編碼的環境和/或正則表達式實現?我使用日語UTF-8語言環境/編碼在Linux中使用Perl,並且它與日文字符不匹配。 – dreamlax 2008-10-15 03:14:58
您始終可以使用字符類[^[:cntrl:]]
來匹配非控制字符。
這不符合Unicode控制字符(在我的環境設置和使用Perl)。有用於改變文本方向等的Unicode控制字符。使用[^ [:ctrnl:]]將匹配這些Unicode字符串,但不匹配ASCII字符串。 – dreamlax 2008-10-15 04:03:56
我認爲你不想或不需要區域設置,但是,而是Unicode。如果你已經解碼了一個文本字符串,\w
將匹配任何語言的單詞字符,\d
匹配不僅僅是0..9
,而是每個Unicode數字等。在正則表達式中,你可以用\p{PropertyName}
查詢Unicode屬性。特別有趣的可能是\p{Print}
。 Here's a list of all the available Unicode character properties。
我寫了一個article about the basics and subtleties of Unicode and Perl,它應該給你一個好主意,讓perl將你的字符串識別爲一個字符序列,而不僅僅是一個字節序列。
更新:使用Unicode,您不會得到語言相關的行爲,而是無論語言如何,都會有默認值。這可能是也可能不是你想要的,但是爲了區分priintable/control character,我不明白你爲什麼需要語言依賴的行爲。
\X
與完全組合的字符(序列)相匹配。證明:
#!/usr/bin/env perl
use 5.010;
use utf8;
use Encode qw(encode_utf8);
for my $string (qw(あ ご ご), "\x{3099}") {
say encode_utf8 sprintf "%s $string", $string =~ /\A \X \z/msx ? 'ok' : 'nok';
}
測試數據爲:正常的字符,-組合前的字符,一個組合字符序列和一個結合字符(其中「不計數」自行,第3章的簡化Unicode)的。
用\X
替代[[:print:]]
以查看Tanktalus的答案在最後兩種情況下產生錯誤匹配。
通過在命令行中提供選項-CS,可以擺脫醜陋的BEGIN {binmode STDIN,「:utf8」} kludge。 – moritz 2008-10-15 06:43:30