2013-12-10 21 views
8

Söz konusu dizede ek bir unicode karakteri "\ ud84c \ udfb4" var. Javadoc'a göre regex uyumu, kod noktası düzeyinde değil karakter düzeyinde yapılmalıdır. Bununla birlikte, aşağıdaki bölünmüş kod düşük vekil (\ udfb4) sözcük olmayan karakter olarak davranır ve üzerine bölünür.Java 7, normal ifadeler ve tamamlayıcı unicode karakterler

Bir şey mi eksik? Kelime olmayan karakterler üzerinde bölmeyi başarmanın diğer alternatifleri nelerdir? (Java sürümü "1.7.0_07")

Şimdiden teşekkürler.

Pattern non_word_regex = Pattern.compile("[\\W]", Pattern.UNICODE_CHARACTER_CLASS); 
String a = "\u529f\u80fd\u0020\u7d76\ud84c\udfb4\u986f\u793a\u5ee3\u544a"; 
String b ="功能 絶顯示廣告"; 
System.out.print("original "+a+"\norginal hex "); 
for(char c : a.toCharArray()){ 
    System.out.print(Integer.toHexString((int)c)); 
    System.out.print(' '); 
} 
System.out.println(); 

String[] tokens = non_word_regex.split(a); 

for(int i =0; i< tokens.length; i++){ 
    String token = tokens[i]; 
    System.out.print(i+" "); 
    for(char c : token.toCharArray()){ 
     System.out.print(Integer.toHexString((int)c)); 
     System.out.print(' '); 
    } 
    System.out.println(); 
} 

Çıkış:
orijinal 功能 絶 顯示 廣告
orjinal heks 529f 80fd 20 7d76 d84c dfb4 986f 793a 5ee3 544A
0 529f 80fd
1 7d76 d84c
2 986f 793a 5ee3 544A

cevap

9

Bu, normal ifade motorundaki bir hataya benziyor. \w ifadesini kullanırsanız, her şey doğru şekilde eşleşir, iki karakterden oluşan tek bir kod noktası olarak kalır. Bu kolayca aşağıdaki kodu çalıştırarak doğrulanabilir:

Pattern pattern = Pattern.compile("(?U)[\\w]"); 
String str = "功能 絶顯示廣告"; 

Matcher matcher = pattern.matcher(str); 
while (matcher.find()) { 
    System.out.println(matcher.toMatchResult().group()); 
} 

Sadece araştırma yoluyla bir hale getirdik ve sorun nerede ben söyleyebilirim. java.util.regex.Pattern'daki compile() yöntemine bakarsanız (1625 satırında başlar), ek karakterler için normal ifadeleri tarar ve taramada destekleyip desteklemeyeceğine karar verir.

Bu yaklaşımdaki sorun, kodun regex'in ek karakter içermemesine rağmen, yine de sizin durumunuzda olduğu gibi bunları uydurmak isteyebileceği gerçeğinin dikkate alınmamasıdır. .

çözümek karakterler içeren bazı regex geliştirmektir, ancak eşleştirme işlemini etkilemez.

Pattern nonWordRegex = Pattern.compile("(?U)(?!\uDB80\uDC00)[\\W]"); 

bölüm (?!\uDB80\uDC00) hile yapar: Ben böyle masum bir şey kullanmanızı öneririz. Bu, ek karakterlerin özel dizisindeki bir karakter için negatif bir görünümdür, yani metin içinde bulamayacağınız anlamına gelir. Ve voila: regex motoru desende ek karakterler olduğunu düşünüyor ve desteklerini açıyor!

+0

Maalesef, Matcher sözcük sınırlarını korumaz. "[^ \\ w]" ifadesini kullanarak, "[\\ W]" ile aynı sonucu verir. Bir yere java kartlarına yapıştırmalı mıyım? – user3088039

+1

@ user3088039 Sadece sorunu çözdüm! Cevabı tekrar kontrol et, güncelledim. – Malcolm

+0

"(? U)" ek karakter desteğini açacağını düşünürsünüz. Kapakların altına baktığınız için teşekkürler. Güzel çalışıyor. – user3088039

İlgili konular