replace需要注意的点($和\的特殊处理)

本文详细介绍了Java中String对象的replace、replaceAll和replaceFirst方法,重点讨论了它们在处理特殊字符和$时的不同行为。在使用replaceAll和replaceFirst时,若参数包含和$,系统会进行特殊处理,可能导致意外结果。为了避免这种情况,建议使用Matcher.quoteReplacement方法对动态参数进行预处理。文章通过实例展示了如何正确处理这些特殊字符,确保字符串替换操作按预期进行。
部署运行你感兴趣的模型镜像

问题

replaceAll/replaceFirst会特殊处理入参(要替换的目标值)中 \ 和 $ 这两个字符,而replace则把它们两个当成字符串处理?

使用replaceAll/replaceFirst时,动态入参需要注意,避免入坑

方法介绍

对String进行字符串替换,有下面三个方法可以使用

replace:直接把入参当字符串处理

replaceAll:会把入参当正则表达式处理

replaceFirst:会把入参当正则表达式处理

原因

当使用replaceAll/replaceFirst时

第一个入参为要替换的值可以为正则表达式,这个没有问题

第二个入参为替换后的值,为字符串,也符合我们之前的使用习惯,但是点进源码中,发现还是有差别的,实际上会对字符串中包含的 \ 和 $ 进行特殊处理(给 $ 这个符号增加功能)

位置:replaceAll/replaceFirst --> Matcher.appendReplacement(while循环中)

从上面代码中可以看出,按字符处理的时候,会对 \ 和 $ 这两个字符进行特殊处理(replacement为第二个入参传入的字符串)


\:如果字符为 \ 的时候,会取下一个字符【如果没有下一位,则抛异常】

$:如果字符为 $ 的时候,会进行特殊处理,即取后面的N个字符,这N个字符需要 { 开头,} 结尾,或者其他规则(规则自行百度)【如果没有下一位,则抛异常。不是 { 开头或 } 结尾,或者其他支持的规则,也抛异常】


\ 主要是为 $ 服务的,即 $ 前面加 \ 则不进行特殊处理,取下一位就是 $ 了

所以我们在传第二个入参目标值的时候,如果只是把 \ 和 $ 当成正常的字符串对待的话,需要加上转义字符 \ ,Matcher中也提供了quoteReplacement对这两个特殊字符进行特殊转换。如果使用replaceAll/replaceFirst,入参是动态的,可以将入参通过Matcher.quoteReplacement处理一下,这样就不用自己去判断了

例子:

// replaceFirst 与 replaceAll同理
System.out.println("abcd".replaceFirst("a", "\\g")); // gbcd
System.out.println("abcd".replaceFirst("a", Matcher.quoteReplacement("\\g"))); // \gbcd
System.out.println("abcd".replaceFirst("a", "$g")); // 抛异常,因为$后面没有特殊处理的规则
System.out.println("abcd".replaceFirst("a", Matcher.quoteReplacement("$g"))); // $gbcd

为什么replace就可以将入参都当成字符串处理?

通过下面代码截图可以看到,其实它也是调用了replaceAll,然后通过特殊处理,来当成字符串而已

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

在使用 JavaScript 的`replace()`方法处理特殊字符时,有以下注意事项: ### 正则表达式中的特殊字符 当使用正则表达式作为`replace()`的第一个参数时,许多字符具有特殊含义,如 `.`(匹配任意单个字符)、`*`(匹配前面的子表达式零次或多次)、`+`(匹配前面的子表达式一次或多次)等。如果要匹配这些字符本身,需要进行转义,即在字符前加上反斜杠`\`。 ```javascript const str = "Hello. World."; // 若要替换号,需进行转义 const newStr = str.replace(/\./g, "!"); console.log(newStr); // 输出: "Hello! World!" ``` ### 替换字符串中的特殊字符 在替换字符串中,有一些特殊的字符序列具有特殊含义,例如`$1`、`$2`、...、`$99`表示与正则表达式中的第 1 到第 99 个子表达式相匹配的文本,`$&`表示与正则表达式相匹配的子串,`$``表示位于匹配子串左侧的文本,`$'`表示位于匹配子串右侧的文本,`$$`表示直接量符号`$` [^4]。 ```javascript const str = "abc"; const newStr = str.replace(/(b)/, "[$&]"); console.log(newStr); // 输出: "a[b]c" ``` ### 处理 Unicode 字符 如果需要处理 Unicode 字符,要确保正则表达式能够正确匹配。在 ES6 及以后的版本中,可以使用`u`标志来处理 Unicode 字符。 ```javascript const str = "😀abc"; const newStr = str.replace(/[\u{1F600}-\u{1F64F}]/gu, "X"); console.log(newStr); // 输出: "Xabc" ``` ### 处理换行符 换行符(如`\n`、`\r`)在正则表达式中也需要特别处理。可以使用`[\s\S]`来匹配任意字符,包括换行符。 ```javascript const str = "Hello\nWorld"; const newStr = str.replace(/[\s\S]/g, "*"); console.log(newStr); // 输出: // ** // **** ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值