2011-09-12 53 views
0

我最近遇到了一些涉及Java的正則表達式引擎的奇怪行爲。正則表達式Java中的黑角...字符順序改變了正則表達式的含義?

當寫一些驗證,我需要方括號添加到我的正則表達式,像這樣:

"[^a-zA-Z0-9_/[email protected] ]" // original expression 
"[^a-zA-Z0-9_/[email protected] /]/[]" // first modificiation 

但是......這個實施失敗。經過實驗後,我發現如果我將空間char移動到最後,它就會起作用。

"[^a-zA-Z0-9_/[email protected]/]/[ ]" // final working modification 

現在使用這個表達式調用代碼使用的方法String.replaceAll(String, String),所列here

我的問題是...有沒有人有任何好的技術理念,爲什麼放置空間改變這個正則表達式的含義?這真的沒關係。

[編輯] 從評論和答案 - 這是一個例子,其中使用內置的字符串方法導致不被捕獲的不正確的行爲。我的運行時環境根本不會抱怨,即使您閱讀了關於String.replaceAll(String, String)的文檔,它也清楚地表明它與Pattern.compile(regex).matcher(str).replaceAll(repl)的功能相同,我認爲我會提交一個錯誤。

+2

** **怎麼沒有失敗?我想你會得到['PatternSyntaxException'](http://download.oracle.com/javase/7/docs/api/java/util/regex/PatternSyntaxException.html)。 –

+0

當你寫'/]/['你想在方括號中包含字符類嗎?如果是這樣,你失敗了,因爲錯誤的轉義字符,並創建了第二個。 – stema

+0

沒有編譯錯誤。它沒有正確捕捉括號失敗。不過,我已經修復了錯誤的語法。謝謝! – avgvstvs

回答

9

您使用錯誤的轉義字符,它是\而不是/

而且,我不知道,如果你想你的角色組,包括/.,或者如果您認爲.需要的字符組進行轉義(不需要進行轉義:它總是代表文字字符組中的.)。

當試圖編譯[^a-zA-Z0-9_/[email protected] /]/[]它給出了這樣的例外:

java.util.regex.PatternSyntaxException: Unclosed character class near index 20 
[^a-zA-Z0-9_/[email protected] /]/[] 
        ^
    at java.util.regex.Pattern.error(Pattern.java:1713) 
    at java.util.regex.Pattern.clazz(Pattern.java:2254) 
    at java.util.regex.Pattern.sequence(Pattern.java:1818) 
    at java.util.regex.Pattern.expr(Pattern.java:1752) 
    at java.util.regex.Pattern.compile(Pattern.java:1460) 
    at java.util.regex.Pattern.(Pattern.java:1133) 
    at java.util.regex.Pattern.compile(Pattern.java:823) 

這表明存在與該點的字符類的問題。事實上:你有一個空字符類[]這是無效的!

[^a-zA-Z0-9_/[email protected] /]/[]指 「字符不匹配(AZ,AZ,0-9,_/.@/)中,隨後接着<斜線/編譯失敗,因爲它是畸形>」 。

你想要的是可能[^[email protected] \]\[]這是 「不匹配A-Z,A-Z,0-9,_.@][字符」。

如果你把它寫在String文字記得要加倍\(因爲他們有String文字特殊的含義,以及!):

Pattern regex = Pattern.compile("[^[email protected] \\]\\[]"); 
+0

我改變了我的語法,但是當我跑錯了這個不正確的方法時,我沒有得到任何異常。 (不是開玩笑,它在我的機器上編譯和運行良好......我已經用了6個星期的時間了。)而且......沒有編譯器的沉默。 – avgvstvs

+0

@avgvstvs:如果你把**只是**'java.util.regex.Pattern.compile(「[^ a-zA-Z0-9 _ /。@ /]/[]」);''在' main'方法並在你的機器上執行?也許你正在使用更寬鬆的另一個'Pattern'實現。 –

+1

這當然會失敗,但不會像在OP中一樣使用'String.replaceAll(String,String)'方法。我認爲這強調了在'.replaceAll()'的實現中的一個明顯的缺陷。 – avgvstvs

相關問題