我想要一個正則表達式替換冒號(:
)並帶有問號(?
),如下所示。
但它應該保存冒號如果它們在裏面單引號('
)。正則表達式在逗號分隔列表中替換冒號前綴除外引用
例如,該輸入字符串:
(:a,:abc,'quoted with :colon, and comma',:more)
應改爲:
(?a,?abc,'quoted with :colon, and comma',?more)
我想要一個正則表達式替換冒號(:
)並帶有問號(?
),如下所示。
但它應該保存冒號如果它們在裏面單引號('
)。正則表達式在逗號分隔列表中替換冒號前綴除外引用
例如,該輸入字符串:
(:a,:abc,'quoted with :colon, and comma',:more)
應改爲:
(?a,?abc,'quoted with :colon, and comma',?more)
這是與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)
。
沒有你的文本的詳細資料,我只會讓一些野生的假設,在這裏你可以看到。
說明
爲了便於說明。我將刪除一些捕獲組()
,這隻對替換有用。
(?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *:[^,]* *(?:,|\)$)
分離出來(請注意,一些線具有在前面的空間,它是正則表達式的一部分):
(?:^\(|\G)
(?:
*'(?:[^'\\]|\\.)*' *,
|
*[^:' ][^,]* *,
)*
*:[^,]* *
(?:,|\)$)
正則表達式中的每一個匹配將包含:不應該被替換令牌,隨後是需要替換的單個令牌。
正則表達式從(?:^\(|\G)
開始,它將在字符串的開頭匹配(
,或從上一匹配位置\G
繼續。
令牌不應該是內容替換要麼引用字符串'(?:[^'\\]|\\.)*'
或[^:' ][^,]*
文本序列不具有'
或:
啓動,並且不包含逗號,
。我允許使用\\.
引用的字符串轉義,這意味着\
後跟任何字符。我允許任何數量的不感興趣的令牌*
。
您可以看到多個空格,然後是*
,這意味着我允許令牌前後的任意間距。
然後我們感興趣的令牌::[^,]*
。
然後正則表達式以(?:,|\)$)
結尾,這意味着它在最後遇到)
或,
。這個結尾部分是\G
工作所必需的。
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)
預期的輸出。但是,它顯然不使用正則表達式。另外請記住,如果您允許轉義引號,我的解決方案將失敗。
+1爲什麼downvote?鮑里斯清楚地表示,它知道作者想要RegExps,但這更強大(特別是,如果要添加轉義),從而提供有效和有用的答案。 –
@jmendeth downvote是足夠公平的 - 當時我的回答是混合的愚蠢和錯誤 –
哦,那麼我想留下評論通知他們(或自己編輯他們)比只是downvoting更好。 :/ –
您可以更換所有被後面的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
,因爲您對每個開盤報價都有收盤報價,因此不會被?
取代。
什麼是文本的BNF語法?我可以寫一個適用於這種情況的正則表達式,但不能保證其他情況。 – nhahtdh
'@ user2001158' **歡迎使用StackOverflow!**我編輯了您的問題以幫助他人更好地理解您的問題。如果它不正確,更新它。 –
@Wiseguy我的錯誤。評論已刪除。 – mmoore