2013-12-09 73 views
0

假設我有一個表達a?.foo("xyz?abc"),我想在a?.foo使用正則表達式來擺脫?但內部沒有"xyz?abc"的一個過濾器內的字符,該怎麼辦?正則表達式:在表達式中而不是引號

注意我用Java

+0

什麼不匹配的引號?可以逃脫報價嗎? –

+0

一個逃脫的報價將被放在一個外部引號內,所以它不應該是一個問題。無與倫比的引號是一個錯誤,不應該在這裏考慮。然而,它需要考慮有多個引號對的情況,例如'a?.foo(「xyz?abc」)。bar(「123?456」)' –

回答

1

您必須首先捕獲雙引號內的內容,例如:

String subject = "a?.foo(\"x\\\"yz?abc\").bar(\"123?456\")"; 
String regex = "(?s)(\"(?>[^\\\\\"]++|\\\\{2}|\\\\.)*\")|\\?"; 
String result = subject.replaceAll(regex, "$1"); 
+0

真棒!我想我應該切換到這一個 –

1
System.out.println("a?.foo(\"xyz?abc\")" 
     .replaceAll("(\".*?\"|\\?)", "$1§") 
     .replaceAll("\\??§", "")); 

我要麼替換字符或字符串「...」用特殊字符未使用§, ,然後用一個可選的字符刪除§在一起。

+0

不錯的解決方案,thx很多。唯一值得關注的是性能方面。但無論如何,我現在要使用這一個 –

0
String s = "a?.foo(\"xyz?abc\")"; 
System.out.println(s.replaceAll("(a\\?\\.)", "a.")); 

但我想這不是你要求的,對嗎?

+0

不,解決方案中不應該存在「a」,這只是一個例子 –

1

這是一個使用MatcherappendReplacement功能的解決方案。

基本上,我們搜索"(notQuestionMark)?(notQuote)",取而代之的是"(notQuestionMark)(notQuote)"

public static void main(String[] args) throws Exception { 
    final String[] ss = {"a?.foo(\"xyz?abc\")", "a?.foo(\"xyz?abc\").bar(\"123?456\")"}; 
    final Pattern patt = Pattern.compile("(\"[^?]*+)\\?([^\"]*+\")"); 
    for(final String in : ss) { 
     final Matcher m = patt.matcher(in); 
     final StringBuffer sb = new StringBuffer(); 
     while(m.find()) { 
      m.appendReplacement(sb, "$1$2"); 
     }    
     m.appendTail(sb); 
     System.out.println(sb.toString()); 
    } 
} 

輸出:

a?.foo("xyzabc") 
a?.foo("xyzabc").bar("123456") 

這可能比使用兩個replaceAll呼叫的方法快,你可以使用Matcher.reset(String s)重用Matcher而實際的搜索和替換隻能進行一次。

重用Matcher看起來是這樣的:

public static void main(String[] args) throws Exception { 
    final String[] ss = {"a?.foo(\"xyz?abc\")", "a?.foo(\"xyz?abc\").bar(\"123?456\")"}; 
    final Matcher m = Pattern.compile("(\"[^?]*+)\\?([^\"]*+\")").matcher(""); 
    for(final String in : ss) { 
     m.reset(in); 
     final StringBuffer sb = new StringBuffer(); 
     while(m.find()) { 
      m.appendReplacement(sb, "$1$2"); 
     }    
     m.appendTail(sb); 
     System.out.println(sb.toString()); 
    } 
} 
+0

聽起來不錯,但我仍然喜歡卡西米爾的答案,因爲它的風格簡單。不過,無論如何,我會給你一個補償。謝謝鮑里斯! –

+0

@green你說得對,那個解決方案很整潔 - 沒有想到從前瞻中捕獲while模式。 –