2013-01-22 17 views
0

我想要一個正則表達式替換冒號(:)並帶有問號(?),如下所示。
但它應該保存冒號如果它們在裏面單引號')。正則表達式在逗號分隔列表中替換冒號前綴除外引用

例如,該輸入字符串:

(:a,:abc,'quoted with :colon, and comma',:more)

應改爲:

(?a,?abc,'quoted with :colon, and comma',?more)
+0

什麼是文本的BNF語法?我可以寫一個適用於這種情況的正則表達式,但不能保證其他情況。 – nhahtdh

+0

'@ user2001158' **歡迎使用StackOverflow!**我編輯了您的問題以幫助他人更好地理解您的問題。如果它不正確,更新它。 –

+0

@Wiseguy我的錯誤。評論已刪除。 – mmoore

回答

1

這是與replaceAll一起使用的另一種解決方案。

原始正則表達式:

((?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *):([^,]* *(?:,|\)$)) 

引用的字符串(在replaceAll使用):

"((?:^\\(|\\G)(?: *'(?:[^'\\\\]|\\\\.)*' *,| *[^:' ][^,]* *,)* *):([^,]* *(?:,|\\)$))" 

更換(在replaceAll使用):

"$1?$2" 

樣品輸入:

 
( :a , :abc, 'quoted with :colon, and comma', skdhfks'sdfkdf , :sdf, 'sdfds\'f', :sdfksdf, sdkhfksd , :dfsd, sdfk'fjsdhfkf, 'werwer', :sdf, :Sdf, skhfskjdf, 'asdads\' :asdkahsd ad' ) 

示例輸出:

 
( ?a , ?abc, 'quoted with :colon, and comma', skdhfks'sdfkdf , ?sdf, 'sdfds\'f', ?sdfksdf, sdkhfksd , ?dfsd, sdfk'fjsdhfkf, 'werwer', ?sdf, ?Sdf, skhfskjdf, 'asdads\' :asdkahsd ad' ) 

基本上,空間之前和之後,自由地允許。如果'不是第一個字符,那麼它不被視爲帶引號的字符串。 '被允許在引用字符串內轉義 - 實際上允許使用\進行任何類型的轉義。空參數是不允許的,例如(:a, , :b)

DEMO

沒有你的文本的詳細資料,我只會讓一些野生的假設,在這裏你可以看到。

說明

爲了便於說明。我將刪除一些捕獲組(),這隻對替換有用。

(?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *:[^,]* *(?:,|\)$) 

分離出來(請注意,一些線具有在前面的空間,它是正則表達式的一部分):

(?:^\(|\G) 
(?: 
*'(?:[^'\\]|\\.)*' *, 
| 
*[^:' ][^,]* *, 
)* 
*:[^,]* * 
(?:,|\)$) 

正則表達式中的每一個匹配將包含:不應該被替換令牌,隨後是需要替換的單個令牌。

正則表達式從(?:^\(|\G)開始,它將在字符串的開頭匹配(,或從上一匹配位置\G繼續。

令牌不應該是內容替換要麼引用字符串'(?:[^'\\]|\\.)*'[^:' ][^,]*文本序列不具有':啓動,並且不包含逗號,。我允許使用\\.引用的字符串轉義,這意味着\後跟任何字符。我允許任何數量的不感興趣的令牌*

您可以看到多個空格,然後是*,這意味着我允許令牌前後的任意間距。

然後我們感興趣的令牌::[^,]*

然後正則表達式以(?:,|\)$)結尾,這意味着它在最後遇到),。這個結尾部分是\G工作所必需的。

2
String str = "(:a,:abc,'quoted with :colon, and comma',:more)"; 
StringBuffer sb = new StringBuffer(); 
boolean inQuote = false; 
for (char c : str.toCharArray()) { 
    if (c == '\'') { 
     inQuote = !inQuote; 
     sb.append(c); 
    } else if (inQuote) { 
     sb.append(c); 
    } else if(c == ':') { 
     sb.append('?'); 
    } else { 
     sb.append(c); 
    } 
} 
str = sb.toString(); 
System.out.println(str); 

可生產的(?a,?abc,'quoted with :colon, and comma',?more)預期的輸出。但是,它顯然不使用正則表達式。另外請記住,如果您允許轉義引號,我的解決方案將失敗。

+0

+1爲什麼downvote?鮑里斯清楚地表示,它知道作者想要RegExps,但這更強大(特別是,如果要添加轉義),從而提供有效和有用的答案。 –

+1

@jmendeth downvote是足夠公平的 - 當時我的回答是混合的愚蠢和錯誤 –

+0

哦,那麼我想留下評論通知他們(或自己編輯他們)比只是downvoting更好。 :/ –

1

您可以更換所有被後面的quotes (')even numbers:。這將至少在這種情況下工作: -

String str = "(:a,:abc,'quoted with :colon, and comma',:more)";  
str = str.replaceAll("[:](?=(?:[^']*'[^']*')*[^']*$)", "?"); 

System.out.println(str); 

輸出: -

(?a,?abc,'quoted with :colon, and comma',?more) 

所以,:quotes內,將永遠不會被後面的偶數個quotes,因爲您對每個開盤報價都有收盤報價,因此不會被?取代。

相關問題