簡體   English   中英

Java對正則表達式庫中的非BMP Unicode字符(即代碼點> 0xFFFF)的支持?

[英]Java support for non-BMP Unicode characters (i.e. codepoints > 0xFFFF) in their Regular Expression Library?

我目前正在使用Java 6(我沒有選擇轉移到Java 7),我正在嘗試使用java.util.regex包來對包含Unicode字符的字符串進行模式匹配。

我知道java.lang.String支持補充字符(即代碼點> 0xFFFF的字符)(自Java 5起),但我沒有看到一種簡單的方法來與這些字符進行模式匹配。 java.util.regex.Pattern仍然只允許使用4位數表示十六進制數(例如\\ uFFFF)

有誰知道我在這里錯過了一個API嗎?

我從來沒有用補充字符進行模式匹配,但我認為它就像編碼它們(在模式和字符串中)一樣簡單,就像兩個16位數字(一個UTF-16代理對)\\ unnnn \\ ummmm。 java.util.regex 應該足夠聰明,可以將這兩個數字(Java字符)解釋為模式和字符串中的單個字符(盡管Java仍會將它們視為兩個字符,作為字符串的元素)。

兩個鏈接:

Java Unicode編碼

http://java.sun.com/developer/technicalArticles/Intl/Supplementary/

從最后一個鏈接(參考Java 5):

java.util.regex包已更新,因此模式字符串和目標字符串都可以包含補充字符,這些字符將作為完整單元處理。

另請注意,如果您使用UTF8作為編碼(對於源文件),您也可以直接編寫它們(請參閱最后一個鏈接中的“在源文件中表示補充字符”一節)。

例如:

    String pat1 = ".*\uD840\uDC00{2}.*";
    String s1  = "HI \uD840\uDC00\uD840\uDC00 BYE";
    System.out.println(s1.matches(pat1) + " len=" + s1.length());

    String pat2 = ".*\u0040\u0041{2}.*";
    String s2 = "HI \u0040\u0041\u0040\u0041 BYE";
    System.out.println(s2.matches(pat2) + " len=" + s2.length());

這是用Java 6編譯的,打印出來的

true len=11
false len=11

與上述內容一致。 在第一種情況下,我們有一個代碼點,表示為一對代理java字符(兩個16位字符,一個多余的Unicode字符), {2}量詞適用於該對(= codepoint)。 在第二個中,我們有兩個不同的BMP字符,量詞適用於最后一個 - 因此,沒有匹配。

但請注意,字符串長度是相同的(因為Java測量的字符串長度計算Java字符,而不是Unicode代碼點)。

最簡單的解決方案是對源代碼使用UTF-8編碼。 然后直接將字符放入。 您永遠不應該在任何程序中指定單獨的代碼單元。

然而,字符類仍然存在問題,因為Java蹩腳暴露的UTF-16內部編碼會使它們混亂。 在JDK7之前不能使用完整的Unicode,即使這樣,您也必須使用間接的\\x{HHHHH}表示法指定邏輯代碼點。 您仍然無法在charclass中包含任何文字代碼點,但您可以使用\\x{H..H}來避開它。

不完美,但它比它好多了。 UTF-16始終是妥協。 內部使用UTF-8或UTF-32的系統沒有這些限制。 它們也永遠不會讓您指定與代碼點不同的代碼單元。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM