0

我想要一个:用问号 ( ?) 替换冒号 ( ) 的正则表达式,如下所示。
但如果冒号在单引号( )内,它应该保留冒号。'

例如,这个输入字符串:

(:a,:abc,'用:冒号和逗号引用',:more)

应改为:

(?a,?abc,'用:冒号和逗号',?more)
4

3 回答 3

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)。但是,它显然没有使用正则表达式。另请记住,如果您允许转义引号,我的解决方案将失败。

于 2013-01-22T17:26:16.740 回答
1

这是另一个适用于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工作所必需的。

于 2013-01-22T17:59:09.153 回答
1

您可以替换:后面的所有even numbersof 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,因此它不会被 . 替换?

于 2013-01-22T17:35:54.687 回答