2011-07-21 230 views
3

正則表達式方言:Java
問題:給定一個字符串,將其中所有出現的子字符串替換掉,除非這些出現在引號內。替換字符串中的子字符串,除非字符串在引號內

例1:

string: "test substr 'test substr' substr" 
substring: "substr" 
replacement: "YYYY" 
output: "test YYYY 'test substr' YYYY" 

例2:

string: "test sstr 'test sstr' sstr" 
substring: "substr" 
replacement: "YYYY" 
output: "test sstr 'test sstr' sstr" 

示例3:

string: "test 'test substr'" 
substring: "substr" 
replacement: "YYYY" 
output: "test 'test substr'" 

這是我最好的嘗試迄今:

Regex: ((?:[^']*'[^']+')*?[^']*?)substring 
Replace: $1replacement 

問題在於它需要在引號內的最後一個字符串之後的引號之外的子字符串,否則它不起作用,所以Example3將失敗(輸出:「test」test YYYY'「)。

非常感謝您的幫助。

回答

4

這裏有一個辦法:

public class Main { 
    public static void main(String [] args) { 

     String[] tests = { 
       "test substr 'test substr' substr", 
       "test sstr 'test sstr' sstr", 
       "test 'test substr'" 
     }; 

     String regex = "substr(?=([^']*'[^']*')*[^']*$)"; 

     for(String t : tests) { 
      System.out.println(t.replaceAll(regex, "YYYY")); 
     } 
    } 
} 

打印:

 
test YYYY 'test substr' YYYY 
test sstr 'test sstr' sstr 
test 'test substr' 

注意,如果'可以用\例如逃脫這不起作用。

快速解釋:

以下:([^']*'[^']*')*將匹配0或偶數個單引號,其間無報價,和[^']*$匹配任何非報價和結束串。

所以,完整的正則表達式匹配substr(?=([^']*'[^']*')*[^']*$)有0或偶數個單引號的超前它的任何"substr",一路尋找到結束串時

尋找所有的方式來結束字符串是關鍵在這裏。如果你不這樣做,下面的"substr"也將被替換:

aaa 'substr' bbb 'ccc ddd' eee 
     ^ ^ ^
      |  |  | 
      i  ii  iii 

,因爲它「看到」偶數的單引號在它前面的(II)。您必須強制它查看右邊的整個字符串(一直到$)!

+0

非常感謝Bart!不知何故,我陷入了複製,從未想過展望未來。 –

+0

@Marius,不客氣。 –