这个答案只是为了证明这种可能性。在生产代码中使用它是有问题的。
使用 Java StringreplaceAll
函数是可能的:
String input = "Hi, Mr.Xyz! Your account number is :- (1234567890) , (.*) &$@%#*(....))(((";
String output = input.replaceAll("\\G((?:[^()\\[\\]{}?+\\\\.$^*|!&@#%_\":<>/;'`~-]|\\Q(.*)\\E)*+)([()\\[\\]{}?+\\\\.$^*|!&@#%_\":<>/;'`~-])", "$1\\\\$2");
结果:
"Hi, Mr\.Xyz\! Your account number is \:\- \(1234567890\) , (.*) \&\$\@\%\#\*\(\.\.\.\.\)\)\(\(\("
另一个测试:
String input = "(.*) sdfHi test message <> >>>>><<<<f<f<,,,,<> <>(.*) sdf (.*) sdf (.*)";
结果:
"(.*) sdfHi test message \<\> \>\>\>\>\>\<\<\<\<f\<f\<,,,,\<\> \<\>(.*) sdf (.*) sdf (.*)"
解释
原始正则表达式:
\G((?:[^()\[\]{}?+\\.$^*|!&@#%_":<>/;'`~-]|\Q(.*)\E)*+)([()\[\]{}?+\\.$^*|!&@#%_":<>/;'`~-])
请注意,\
当在字符串中指定正则表达式时,它会再次转义,并且"
需要转义。上面可以看到字符串中生成的正则表达式。
原始替换字符串:
$1\\$2
由于$
在替换字符串中具有特殊含义,并且您希望将其保留为$2
,因此您需要转义 ,\
这样\
就不会转义$
. 并将替换字符串放在带引号的字符串中,您需要\
将\
.
在我们剖析怪物之前,让我们谈谈这个想法。我们将使用非特殊字符,以及我们不想替换的序列,并且尽可能多地使用。下一个字符要么是不构成我们不想替换的序列的特殊字符,要么是字符串的结尾(这意味着我们已经找到了所有需要替换的字符(如果有的话))。
自然,我们可以将任意字符串视为由以下许多连续模式组成:[0 or more (non-special character or special pattern not to be replace)][special character]
,并且字符串以 . 结尾[0 or more (non-special character or special pattern not to be replace)]
。
replaceAll
与不带正则表达式的函数一起使用时,\G
可能会找到不连续的匹配项,这可能会在不被替换的序列中间切开并弄乱。\G
表示最后一场比赛的边界,可用于确保下一场比赛从上一场比赛结束的地方开始。
整个正则表达式将匹配最小长度为 1(特殊字符)的字符串。第一个捕获组包含不应替换的部分,第二个捕获组包含应替换的特殊字符。