`

String字符串替换的一个诡异问题

 
阅读更多
将字符串中的数字替换成$D

希望将以下字符串中的数字替换为$D字符
引用

   ab1cd2


我们知道String有3个用于字符替换的方法,分别是:
  • String replace(CharSequence target, CharSequence replacement):将字符串中出现的target替换成replacement;
  • String replaceAll(String regex, String replacement):regex是一个正则表达式,将字符串中匹配的子字符串替换为replacement;
  • String replaceFirst(String regex, String replacement):和replaceAll(..)类似,只不过只替换第一个出现的地方。


由于我们希望所有替换,因此使用如下方法:
代码1:StringReplaceTest
public class StringReplaceTest {
    @Test
    public void testReplace(){
        String str = "ab1cd2";
        System.out.println(str.replaceAll(str, "$D"));
    }
}


小小代码现诡异异常

运行StringReplaceTest,控制台却没有返回正确的结果,而是抛出如下的异常:
引用

java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Matcher.java:713)
at java.util.regex.Matcher.replaceAll(Matcher.java:813)
at java.lang.String.replaceAll(String.java:2189)
at com.hsit.euler.qform.engine.jdbc.StringReplaceTest.testReplace(StringReplaceTest.java:17)


比较诡异吧,难道是JDK的BUG???

剥丝入茧,原来如此

其实String的replaceAll()及replaceFirst()方法内部都是调用java.util.regex.Matcher的String replaceAll(String replacement)方法的。让我们把刚才的诧异放在一边,好好看下这个方法的Javadoc,掐头去尾,主要是这段:
引用

     * <p> Note that backslashes (<tt>\</tt>) and dollar signs (<tt>$</tt>) in
     * the replacement string may cause the results to be different than if it
     * were being treated as a literal replacement string. Dollar signs may be
     * treated as references to captured subsequences as described above, and
     * backslashes are used to escape literal characters in the replacement
     * string.


原来是我们的替换目标串中包含了$这个特殊的字符,因为替换串使用这个引用正则表达式匹配的组,$0代表匹配项,$1代表第1个匹配分组,$1代表第2个匹配分组--终于真相大白了,是我们闯了雷区了

来看一个例子加深一个印象:

    @Test
    public void testReplace2(){
        String str = "刘备是张飞的小弟";
        System.out.println(str.replaceAll("(刘备)是(张飞)", "$2是$1"));
        //=>张飞是刘备的小弟
    }


李鬼出来,李逹进去
李鬼现形,处理起来自然简单:
    @Test
    public void testReplace(){
        String str = "ab1cd2";
        System.out.println(str.replaceAll(str, "\\$D"));
        //=>ab$Dcd$D
    }



小评一下

如果JDK可以再分析一下$,将$N即N是数字时才对其进行特殊处理,否则就不当成特殊字符,是不是更好一些呢?

也许这样并不好,必须这样造成Matcher方法为了这个小概率事件做很多复杂的检查,结果是得不偿失的。还是遇到特殊字符报异常,让开发者去处理更好些,这是28原来取舍得当的一个API设计。既然$是特殊字符,开发者绕过即可。
分享到:
评论

相关推荐

    Delphi字符串快速替换函数,速度超快 秒杀自带的StringReplace函数

    它接受四个参数:原始字符串`S`,要查找的子串`Find`,替换后的子串`Replace`,以及一个标志`Flags`来控制替换行为。然而,由于`StringReplace`内部实现的原因,当处理大量替换或长字符串时,它的效率会下降,因为它...

    oracle字符串替换

    - **替换字符串**:`'|'`,用单个竖线字符替换匹配到的所有连续的两个或多个竖线字符。 - **执行结果**:`'123|456|789|191|000|234'` 通过以上操作,原始字符串中的多余竖线被成功简化为单个竖线,达到了预期的...

    String 字符串操作、比较、查找字符、替换、反转、分割等

    - `split(String regex)`:根据给定的正则表达式将字符串分割成多个子字符串,并返回一个包含这些子字符串的数组。 ### 示例代码 ```java public class TestJavaDemo01 { public static void main(String[] args)...

    java 文本字符串替换工具

    在Java编程语言中,文本字符串替换是一个常见的任务,特别是在处理大量文本数据时。这个"java 文本字符串替换工具"很可能是为了帮助开发者高效地搜索和替换文件中的特定文本内容。让我们详细了解一下如何在Java中...

    字符串查找与替换程序 文件

    字符串替换函数是一个常用的字符串处理函数,其主要功能是将指定字符串中指定的字符串替换为新的字符串。本函数的实现过程可以分为以下几个步骤: 1. 参数检查:首先,函数会检查输入参数的合法性,包括源字符串、...

    详解C++ string常用截取字符串方法

    在C++编程中,`std::string`是一个非常重要的数据类型,用于表示和操作字符串。本文将详细解析两种常用的C++ `std::string`截取字符串的方法:`find`和`find_last_of`,以及如何结合使用它们来满足各种字符串处理...

    比CString更高效的字符串替换

    本话题聚焦于一个优化过的字符串替换方法,针对原生MFC库中`CString::Replace`函数性能问题进行改进。`CString`是Microsoft Foundation Class (MFC) 库中的一个类,用于方便地处理和操作字符串,但有时其性能可能不...

    文件字符串替换工具

    字符串替换,顾名思义,是指在文本文件中找到特定的字符串并用另一个字符串替换的过程。在C++中,我们可以利用标准库中的`std::string`类和相关函数来完成这一任务。例如,`std::string::find`用于查找子串,`std::...

    fortran分割字符串和字符串替换的子程序_Fortran_

    Fortran提供了一个内置函数`replace()`(或`tranlate()`),可以用来替换字符串中的特定字符或子串。但是,如果需要更复杂的替换规则,例如根据某种模式替换,可能需要自定义子程序。下面是一个简单的字符串替换...

    apache和string字符串替换的比较

    首先,`String`类的`replace`方法是一个原地替换方法,它接受两个参数:要查找的字符序列(源)和用于替换的字符序列(目标)。例如,如果你有一个字符串`s = "Hello, World!"`,你可以使用`s.replace("World", ...

    java字符串替换 代码转换相关源码.rar

    java字符转换类代码,可以实现判断字符串是否为空,并删除首尾空格,字符串替换函数,代码转换,GBK转换为ISO-8859-1,代码转换 从srcCode转换为destCode,代码转换,GBK转换为big5,替换非法字符,标记本身等于分隔...

    一次查找替换文本中多个字符串(添加还原功能)

    这个Java开发的应用程序允许用户批量地在文本文件中查找并替换多个特定的字符串,同时它还具有一个独特的功能——替换还原,这在误操作或需要恢复原始文本时显得尤为有用。 首先,我们来了解一下“查找与替换”功能...

    string字符串自动格式化单引号分隔工具

    "string字符串自动格式化单引号分隔工具"就是一个专为简化这一任务而设计的应用。它能够自动将一个字符串按照指定的单引号进行分隔,以便于在SQL的IN查询语句中更方便地使用。 首先,我们要理解什么是字符串。在...

    vb6字符串替换工具

    在VB6(Visual Basic 6)环境中,字符串处理是一项常见的任务,而“vb6字符串替换工具”正是这样一个专为处理字符串替换问题而设计的应用程序。它提供了用户友好的界面和功能,使得程序员或普通用户能够方便地在文本...

    c#批量替换某一类字符串

    在C#编程中,批量替换某一类字符串是一个常见的任务,特别是在处理大量文本数据时,例如日志分析、代码自动生成或者文本格式转换等场景。这个任务可以通过多种方式实现,但最常用的是使用`String`类的`Replace`方法...

    把旧的字符串换成新的字符串

    把旧的字符串替换成新的字符串 s oldstr newstr

    EXE/DLL文件字符串替换工具showstring汉化版.rar

    软件介绍: showstring能够打开可执行文件EXE/DLL,从中搜索并替换指定的字符串。支持ASCII/UNICODE类型的字符串。能逐个字符地扫描文件,根据选项要求来设定如何搜索。

    React 替换字符串里面span的里的某些内容

    2. 前提是替换字符串里面的某些标签,也可以是多个标签,这个是在react里面的,自己可以参考然后可以动态替换成其他标签,例如li,ul都是可以的 3.字符串可以替换单个也可以替换多个的 4. 原先的想法是获取到字符串...

    字符串替换位置代码

    在这个问题中,我们需要实现一个特定的功能:如果字符串A包含字符串B,我们需要找到B在A中的位置,然后将B倒序并在原位置上替换它。这个功能涉及到的主要知识点有字符串查找、字符串反转和字符串替换。 首先,我们...

    基于Keil实现字符串函数string.h的简单应用

    基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用基于Keil实现字符串函数string.h的简单应用...

Global site tag (gtag.js) - Google Analytics