我想要一个:
用问号 ( ?
) 替换冒号 ( ) 的正则表达式,如下所示。
但如果冒号在单引号( )内,它应该保留冒号。'
例如,这个输入字符串:
(:a,:abc,'用:冒号和逗号引用',:more)
应改为:
(?a,?abc,'用:冒号和逗号',?more)
我想要一个:
用问号 ( ?
) 替换冒号 ( ) 的正则表达式,如下所示。
但如果冒号在单引号( )内,它应该保留冒号。'
例如,这个输入字符串:
(:a,:abc,'用:冒号和逗号引用',:more)
应改为:
(?a,?abc,'用:冒号和逗号',?more)
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)
。但是,它显然没有使用正则表达式。另请记住,如果您允许转义引号,我的解决方案将失败。
这是另一个适用于replaceAll
.
原始正则表达式:
((?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *):([^,]* *(?:,|\)$))
带引号的字符串(用于replaceAll
):
"((?:^\\(|\\G)(?: *'(?:[^'\\\\]|\\\\.)*' *,| *[^:' ][^,]* *,)* *):([^,]* *(?:,|\\)$))"
替换(用于replaceAll
):
"$1?$2"
样本输入:
( :a , :abc, '引用:冒号和逗号', skdhfks'sdfkdf , :sdf, 'sdfds\'f', :sdfksdf, sdkhfksd , :dfsd, sdfk'fjsdhfkf, 'werwer', :sdf, :Sdf, skhfskjdf, 'asdads\' :asdkahsd ad' )
样本输出:
( ?a , ?abc, '用:冒号和逗号引用', skdhfks'sdfkdf , ?sdf, 'sdfds\'f', ?sdfksdf, sdkhfksd , ?dfsd, sdfk'fjsdhfkf, 'werwer', ?sdf, ?sdf, skhfskjdf, 'asdads\' :asdkahsd ad' )
基本上,前后的空格,
是自由允许的。如果'
不是第一个字符,则不被视为带引号的字符串。'
允许在带引号的字符串中转义 - 实际上任何类型的转义\
都是允许的。不允许使用空参数,例如(:a, , :b)
.
如果没有您的文本的详细说明,我将在这里做出一些疯狂的假设,如您所见。
解释
为了便于解释。我将删除一些捕获组()
,这仅对替换有用。
(?:^\(|\G)(?: *'(?:[^'\\]|\\.)*' *,| *[^:' ][^,]* *,)* *:[^,]* *(?:,|\)$)
把它分开(注意有些行前面有空格,它是正则表达式的一部分):
(?:^\(|\G)
(?:
*'(?:[^'\\]|\\.)*' *,
|
*[^:' ][^,]* *,
)*
*:[^,]* *
(?:,|\)$)
正则表达式的每个匹配项都将包含:不应替换的标记,后跟一个需要替换的标记。
正则表达式以 开头(?:^\(|\G)
,它将(
在字符串的开头匹配,或者从最后一个匹配的位置继续\G
。
不应替换的标记是带引号的字符串'(?:[^'\\]|\\.)*'
或不以or开头且不包含逗号[^:' ][^,]*
的文本序列。我允许使用 转义带引号的字符串,这意味着后跟任何字符。我允许任意数量的不感兴趣的令牌。'
:
,
\\.
\
*
您可以看到一些空格后跟*
,这意味着我允许在标记前后有任意间距。
然后是我们感兴趣的token::[^,]*
.
然后正则表达式以 结尾(?:,|\)$)
,这意味着它)
在结尾处遇到,或,
. 这个结尾部分是\G
工作所必需的。
您可以替换:
后面的所有even numbers
of 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
,因此它不会被 . 替换?
。