2015-04-14 44 views
1

這裏是我的正則表達式:如何在沒有Java 7的正則表達式字符串中匹配大於 uFFFF的Unicode代碼點?

(?x)(?:[A-Za-z:_] | [\\xC0-\\xD6]| [\\xD8-\\xF6] | [\\xF8-\\x{2FF}] | [\\x{370}-\\x{37D}] | [\\x{37F}-\\x{1FFF}] | [\\x{200C}-\\x{200D}] | [\\x{2070}-\\x{218F}] | [\\x{2C00}-\\x{2FEF}] | [\\x{3001}-\\x{D7FF}] | [\\x{F900}-\\x{FDCF}] | [\\x{FDF0}-\\x{FFFD}] | [\\x{10000}-\\x{EFFFF}]) 

Regular expression visualization

的Java拒絕編譯。它引發了這個例外:

java.util.regex.PatternSyntaxException: Illegal hexadecimal escape sequence near index 68 
^/((?:(?x)(?:(?x)(?:[A-Za-z:_] | [\xC0-\xD6]| [\xD8-\xF6] | [\xF8-\x{2FF}]... 
                    ^

怎麼了?

爪哇6

+0

看到這個http://stackoverflow.com/questions/3613759/x-escape-in​​-java –

回答

0

這是我如何解決我的問題:

String regex = "(?x)" + 
     "(?:" + 
     "[A-Za-z:_]  |" + 
     "[\\xC0-\\xD6]  |" + 
     "[\\xD8-\\xF6]  |" + 
     "[\\xF8-\\u02FF] |" + 
     "[\\u0370-\\u037D] |" + 
     "[\\u037F-\\u1FFF] |" + 
     "[\\u200C-\\u200D] |" + 
     "[\\u2070-\\u218F] |" + 
     "[\\u2C00-\\u2FEF] |" + 
     "[\\u3001-\\uD7FF] |" + 
     "[\\uF900-\\uFDCF] |" + 
     "[\\uFDF0-\\uFFFD] |" + 
     "[\ud800\udc00-\udb7f\udfff]" + 
)"; 

感謝您的幫助球員。

參考:

0

的BNF圖表僅適用於爪哇7以上。對於Java 6,Java RegExp,\x預計只有兩個十六進制數字,不多也不少。如果您需要匹配Unicode,請使用\u,後跟正好四個十六進制數字。

在你的情況,這將是... [\xF8-\u02FF] ...

這樣做的原因是,Java的正則表達式不使用模式作爲字符的佔位符。相反,Java編譯器會創建Unicode代碼點並將其收集到Unicode字符串中,然後將其傳遞給RegExp工具。因此,正則表達式工具永遠不會看到\x\u(這也是爲什麼你對這個評論編譯錯誤的原因:// See c:\User\...

對於Unicode代碼點>0xFFFF,你需要使用surrogate pairs。您可以使用Character.toChars()創建它們。 Character.toChars(0x10000)創建代表\\x{10000}的兩個char

+0

你有這個翻譯任何線索:' [\\ x {10000} - \\ x {EFFFF}]'? – Stephan

+1

這些代碼不映射到16位Unicode代碼點。您將需要使用名爲「[代理對](http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#unicode)」的東西。您可以使用'Character.toChars(0x10000)'來創建兩個代表'\\ x {10000}'的char。 –

3

\x{h...h}符號,用大括號和十六進制數字的非固定數量的,沒有添加到java.util.regex.Pattern直到爪哇7:

(搜索該頁面\x{。只有後者環節都有它。)

相反,你會需要使用\uhhhh表示法:[\\xF8-\\u02FF]

然而,\uhhhh表示UTF-16編碼單元,即一個Java char,而不是一個完整的Unicode代碼點,因此您的正則表達式的最後一部分— [\\x{10000}-\\x{EFFFF}] —是棘手的翻譯。我認爲Java 6正則表達式完全依賴於代碼單元,因此您實際上需要將它視爲兩個代碼單元:[\\uD800-\\uDB7F][\\uDC00-\\uDFFF](其中[\\uD800-\\uDB7F]是「高」代理的相關子範圍,而[\\uDC00-\\uDFFF]是整個範圍的「低「替代品;幸運的是,U + EFFFF在一系列代碼點的末尾以相同的高代理出現,否則你需要做更復雜的事情)。 (免責聲明:未經測試。)

+0

你有翻譯這個的解決方案嗎:'[\\ x {10000} - \\ x {EFFFF}]'? – Stephan

+0

@Stephan:我不確定。我已經編輯了我的答案以提供可能的解決方案,但我沒有對其進行測試。 – ruakh

+0

我發現了一個和我一樣有同樣問題的人。我在這裏找到了他的解決方案:http://groovy.329449.n5.nabble.com/Unicode-code-points-gt-uFFFF-in-string-literals-regex-td5105310.html。儘管感謝您的幫助;) – Stephan

相關問題