我希望有一个正则表达式用冒号(:
)替换冒号(?
),如下所示。
但如果它们位于单引号('
)内,它应该保留冒号。
例如,此输入字符串:
(:a,:abc,'quoted with :colon, and comma',:more)
应改为:
(?a,?abc,'quoted with :colon, and comma',?more)
答案 0 :(得分: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)
的预期输出。但是,它显然没有使用正则表达式。另外请记住,如果您允许转义引号,我的解决方案将会失败。
答案 1 :(得分:1)
您可以替换:
even numbers
之后的所有quotes (')
。它至少适用于这种情况: -
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
,因为您有每个开头报价的收盘价,因此它不会被?
替换。
答案 2 :(得分: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)
。
如果没有详细的文字说明,我会在这里做一些疯狂的假设。
<强>解释强>
为了便于说明。我将删除一些捕获组()
,这只对替换有用。
(?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *:[^,]* *(?:,|\)$)
将它分开(注意前面有些行有空格,它是正则表达式的一部分):
(?:^\(|\G)
(?:
*'(?:[^'\\]|\\.)*' *,
|
*[^:' ][^,]* *,
)*
*:[^,]* *
(?:,|\)$)
正则表达式的每个匹配将包含:不应替换的标记,后跟需要替换的单个标记。
正则表达式从(?:^\(|\G)
开始,它将匹配字符串开头的(
,或从上一个匹配\G
的位置继续。
不应替换的标记是引用的字符串'(?:[^'\\]|\\.)*'
或[^:' ][^,]*
文本序列,不以'
或:
开头,并且不包含逗号,
。我允许使用\\.
在引用的字符串中转义,这意味着\
后跟任何字符。我*
允许任意数量的不感兴趣的令牌。
你可以看到*
之后的空格,这意味着我允许在令牌之前和之后的任意间距。
然后我们感兴趣的令牌::[^,]*
。
然后正则表达式以(?:,|\)$)
结束,这意味着它在最后遇到)
,或者,
。这个结尾部分是\G
工作所必需的。