精华内容
下载资源
问答
  • replaceall
    千次阅读
    2021-02-28 08:01:39

    用到Json与replaceAll

    Http拦截脚本中经常需要替换,replace虽然不需要处理特殊字符,但是不能匹配多个,ReplaceAll能够使用正则,不过需要处理的转移实在太多

    比如,需要替换一次\,需要输入四次\,而其他脚本进行注册表写入时,又需要转移那么需要输入8次\,对于这种情况,又不能简单的把所有斜杠翻倍。

    简单点处理方式,

    replace("\\4","\\\\");

    采用自定义关键字,替换4次斜杠

    下面是replaceAll处理特殊字符所需要斜杠个数

    package json;

    public class ReplaceAllTest {

    public static void main(String[] args) {

    //正则表达式中特殊字符需要//转义  ^词首 $词尾 *多个字符串>0 +多个字符串>1 ()左右括号

    puts("a~!@#$%^&*()_+b".replaceAll("~!@#\\$%\\^&\\*\\(\\)_\\+", "11~!@#\\$%^&*()_+11"));  //$在后面的字符串中需要转义

    puts("a`-=b".replaceAll("`-=", "22`-=22"));

    puts("----keyboard2----");

    puts("a[b","a[b".replaceAll("\\[", "33[44"));  //左方括号需要转义

    puts("a{b","a{b".replaceAll("\\{", "33{44"));  //左大括号需要转义

    puts("a]}b","a]}b".replaceAll("]}", "33]}44"));

    puts("a\\b","a\\b".replaceAll("\\\\", "11\\\\22"));  //斜杠,需要两次转义才是输出结果

    puts("a3|4b","a3|4b".replaceAll("3\\|4", "11|22"));     //竖杆,正则表示或,需要转义

    puts("----keyboard3----");

    puts("a;:'\"b","a;:'\"b".replaceAll(";:'\"", "11;:'\"22")); //引号,只需要一个转义/,两个报错,三个与一个同样效果

    puts("a;:'\"b","a;:'\"b".replaceAll(";:'\\\"", "11;:'\\\"22"));

    puts("a\\\"b","a\\\"b".replaceAll("\\\\\"", "111"));

    puts("a\\\"b","a\\\"b".replaceAll("\\\\\\\"", "111"));

    puts("----keyboard4----");

    puts("a,.<>b/","a,.<>b/".replaceAll(",\\.<>/", "11,.<>/22"));

    puts("a?b","a?b".replaceAll("\\?", "11?22"));         //问号,正则中表示0~1个前面字符串

    puts("特殊字符中,正则表达式用到的字符都需要\\进行转义");

    puts("需要关注\"、\\前面的斜杠可以看作本身的一部分 ");

    puts("需要关注$, 替换后的$同样需要进行转义");

    puts("-----正则---转义字符--------");

    puts("a33b".replaceAll("\\d+", "11\\\\d+22")); //正常转义字符使用--替换数字

    puts("a-3a3-b".replaceAll("-(\\w+)-", "11\\\\w+22")); //正常转义字符使用--替换字母或数字

    puts("a\\db".replaceAll("\\\\d", "11\\\\d22"));//替换字符串中的\d 为11\d22---与替换\一样

    puts("a\\wb".replaceAll("\\\\w", "11\\\\w22")); //替换字符串中的\w 为11\w22---与替换\一样

    puts("a\\$b".replaceAll("\\\\\\$", "11\\\\\\$22")); //替换字符串中的\$ 为11\$22---与替换\+$一样\\\\+\\$

    puts("-------------综上 单个字符斜杠使用-----"

    + "\r\n只需要一次斜杠的有\" "

    + "\r\n需要两次斜杠的有:表示自身$ ^ ( ) { [ | ? * . + "

    + "\r\n需要两次斜杠的有:表示正则d D w W s S t r n b..."

    + "\r\n需要三次斜杠的有:表示自身\" 与一次效果相同 "

    + "\r\n需要四次斜杠的有:表示自身\\ "

    + "\r\n---------两个字符斜杠使用---------------"

    + "\r\n例如替换\\d,需要四次斜杠"

    + "\r\n例如替换\\\",需要五次斜杠"

    + "\r\n例如替换\\{ \\$ \\*,需要六次斜杠"

    + "\r\n例如替换\\\",使用七次斜杠与五次一样"

    );

    //puts("----中文字符-当作普通字符使用-----");

    //puts("c~!@#¥%……&*()——+-=n".replaceAll("~!@#¥%……&*()——+-=","11~!@#¥%……&*()——+-=00"));

    //puts("a[]{}、|b".replaceAll("[]{}、|", "11[]{}、|00"));

    //puts("a;:‘’“”b".replaceAll(";:‘’“”", "11;:‘’“”00"));

    //puts("a,。《》/?b".replaceAll(",。《》/?", "11,。《》/?00"));

    }

    public static void puts(String s){

    System.out.println(s);

    }

    public static void puts(String s,String s2){

    System.out.println(s+"\t"+s2);

    }

    }

    输出结果为

    a11~!@#$%^&*()_+11b

    a22`-=22b

    ----keyboard2----

    a[ba33[44b

    a{ba33{44b

    a]}ba33]}44b

    a\ba11\22b

    a3|4ba11|22b

    ----keyboard3----

    a;:'"ba11;:'"22b

    a;:'"ba11;:'"22b

    a\"ba111b

    a\"ba111b

    ----keyboard4----

    a,.<>b/a,.<>b/

    a?ba11?22b

    特殊字符中,正则表达式用到的字符都需要\进行转义

    需要关注"、\前面的斜杠可以看作本身的一部分

    需要关注$, 替换后的$同样需要进行转义

    -----正则---转义字符--------

    a11\d+22b

    a11\w+22b

    a11\d22b

    a11\w22b

    a11\$22b

    -------------综上 单个字符斜杠使用-----

    只需要一次斜杠的有"

    需要两次斜杠的有:表示自身$ ^ ( ) { [ | ? * . +

    需要两次斜杠的有:表示正则d D w W s S t r n b...

    需要三次斜杠的有:表示自身" 与一次效果相同

    需要四次斜杠的有:表示自身\

    ---------两个字符斜杠使用---------------

    例如替换\d,需要四次斜杠

    例如替换\",需要五次斜杠

    例如替换\{ \$ \*,需要六次斜杠

    例如替换\",使用七次斜杠与五次一样

    更多相关内容
  • ReplaceAll

    2021-01-25 08:07:21
    ReplaceAll 多文件文本批量替换工具 依赖.net framework2.0
  • string.prototype.replaceall 用于String.prototype.replaceAll的ES Proposal规范填充程序。 如果不可用或不String.prototype.replaceAll调用其“ shim”方法对String.prototype.replaceAll进行填充。 该软件包...
  • replace和replaceAll是JAVA中常用的替换字符的方法,它们的区别是:  1)replace的参数是char和CharSequence,即可以支持字符的替换,也支持字符串的替换(CharSequence即字符串序列的意思,说白了也是字符串);  2)...
  • var replaceall = require("replaceall"); 使用替换 var result = replaceall ( "instances of this" , "with this string" , "in this string" ) ; 例子 var original = "hello world goodbye world" ; ...
  • 主要介绍了Java中replace与replaceAll区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • Java中的replaceAll()方法怎么才能同时替换多个不同的字符串呢? 正好我遇到过这个情况,就跟她分享了一下心得,解决问题后的她开心的像刚充完气儿一样。 这让我颇感欣慰,在这里我也分享给大家。 需求场景 场景1: ...
  • 本文是对JS中实现replaceAll的方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
  • JS 没有提供replaceAll这样的方法。使用正则表可以达成Replace 的效果,感兴趣的朋友看看下面的示例
  • 主要给大家介绍了关于String.replaceAll方法,正则妙用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • 而str.replace(/\-/g,”!”)则可以全部替换掉匹配的字符(g为全局标志)。 replace() The replace() method returns the string that results when you replace text matching its first argument (a regular ...
  • 方法: string.replace(new RegExp(oldString,”gm”),newString)) gm 分别代表: g=global, m=multiLine 大致上方法就是这样的,可以实现替换全部指定字串 另一个简单的验证JS的方法: 在浏览器地址栏输入 [removed]...
  • 本文实例讲述了jQuery中replaceAll()方法用法。分享给大家供大家参考。具体分析如下: 此方法用匹配元素去替换指定的内容。 replaceAll()方法的作用和replaceWith()方法是完全一样的。 语法结构: 代码如下:$...
  • 介绍了js replace 与replaceall实例用法详解,有需要的朋友可以参考一下
  • replaceall.java

    2019-12-28 10:34:30
    数据结构 二叉树 替换子树replaceAll \***********************************************************************************************/
  • 主要介绍了JavaScript实现的字符串replaceAll函数代码分享,本文直接给出实现代码,需要的朋友可以参考下
  • 主要介绍了java中replace()和replaceAll()的区别,两者都是常用的替换字符的方法,感兴趣的小伙伴们可以参考一下
  • 相信会java的同学估计都用过replace、replaceAll、replaceFirst这三个函数,可是,我们真的懂他们吗?下面通过这篇文章大家再来好好学习学习下这几个函数。
  • 主要给大家介绍了关于Java replaceAll()方法报错Illegal group reference的解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
  • java replaceall 用法

    2021-02-28 08:00:37
    Java代码 publicclassTryDotRegEx{publicstaticvoidmain(String[]args){//TODOAuto-generatedmethodstubStringstr="111.3.22.11";str=str.replaceAll("(^|\\.)(\\d)(\\.|$)","$100$2$3");str=str.replaceAll...

    Java代码 9ea8afad69b76ab4759cd9ec2842602a.gif 72e71edaa959e034eb4226637ccb4b64.png

    92a32df3b88d3be3ab0c89b40687ec20.gif

    publicclassTryDotRegEx {

    publicstaticvoidmain(String[] args) {

    // TODO Auto-generated method stub

    String str ="111.3.22.11";

    str=str.replaceAll("(^|\\.)(\\d)(\\.|$)","$100$2$3");

    str=str.replaceAll("(^|\\.)(\\d{2})(\\.|$)","$10$2$3");

    str=str.replaceAll("(^|\\.)(\\d{2})(\\.|$)","$10$2$3");

    str=str.replaceAll("(^|\\.)(\\d{1})(\\.|$)","$100$2$3");

    System.out.println(str);

    }

    }

    public class TryDotRegEx {

    public static void main(String[] args) {

    // TODO Auto-generated method stub

    String str = "111.3.22.11";

    str=str.replaceAll("(^|\\.)(\\d)(\\.|$)","$100$2$3");

    str=str.replaceAll("(^|\\.)(\\d{2})(\\.|$)","$10$2$3");

    str=str.replaceAll("(^|\\.)(\\d{2})(\\.|$)","$10$2$3");

    str=str.replaceAll("(^|\\.)(\\d{1})(\\.|$)","$100$2$3");

    System.out.println(str);

    }

    }

    打印结果:111,003,022,011;

    正则表达式,关于String.replaceALL(..)

    Java代码 9ea8afad69b76ab4759cd9ec2842602a.gif 72e71edaa959e034eb4226637ccb4b64.png

    92a32df3b88d3be3ab0c89b40687ec20.gif

    classt1 {

    publicstaticvoidmain(String a[]) {

    String s ='E:\\jbx\\x9\\io9';

    String ss;

    //把路径s中的'\'换为'\\',为何还要整8个'\'?我以为4个就行了。

    ss = s.replaceAll('\\\\', '\\\\\\\\')

    System.out.println('s= '+ s);

    System.out.println('ss='+ ss);

    //output:

    //s= E:\jbx\x9\io9

    //ss=E:\\jbx\\x9\\io9

    }

    }

    class t1 {

    public static void main(String a[]) {

    String s = 'E:\\jbx\\x9\\io9';

    String ss;

    //把路径s中的'\'换为'\\',为何还要整8个'\'?我以为4个就行了。

    ss = s.replaceAll('\\\\', '\\\\\\\\')

    System.out.println('s= ' + s);

    System.out.println('ss=' + ss);

    //output:

    //s= E:\jbx\x9\io9

    //ss=E:\\jbx\\x9\\io9

    }

    }

    这里的关键是String.replaceAll()是用regular expression 来作为参数的。但是java本身的字符串对于转义符\也有类似的处理。首先,java会把“\\\\”解释成一个字符串(其中包含两个char)——“\ \”这个就是你在JDK的文档里看到的。

    接下来,由于replaceAll是以正则表达式作为参数,所以“\\”被解释成一个regex。对于一个regex来说这就代表着一个字符,就是“\”。对后面的那个8个\来说,最终会被解释成“\\”。

    换言之,假设String.replaceAll()是以普通字符串,而不是regex作为参数,那么这样写代码: String target = source.replaceAll('\\', '\\\\'); 就可以了。

    ===============================

    在replaceAll(String,String)方法中需要特殊处理英文状态的括号,在网上找了一下,可以使用下面的写法将英文括号替换成其他字符(比如中文全角括号):str1.replaceAll("\\(","(");

    Java String replaceAll and regex

    在java中要将一个字符串的中$符号去除。我是这样写的:

    String tmp = "-$125402.00";

    tmp.replaceAll("$","");

    可是执行去来的结果并没有把$去除。后来找资料才发现要这样写

    tmp.replaceAll("\\$","")才可以。

    String replaceAll(String regex, String replacement)中的两个参数都是regex。尤其是当第二个参数replacement是用户输入或指定的字符串时,如果其中包含regex特殊字符(主要是\和$)而不加注意,就容易导致问题引发异常。这种情况下如果只是简单的字符串替换而无需regex引擎参与的话,就不要用 replaceAll好了。JDK1.5中加入了String replace(CharSequence target, CharSequence replacement),可以用它。JDK1.4或以下,自己搞一个好了,如oldReplace:http://www.javapractices.com/Topic80.cjp

    我在写程序的时候,需要将"\"字符写入一个文本文件,开始以为这不是个什么问题,转换一下就好了嘛,代码如下:

    targetPath = targetPath.replaceAll("\\", "\\\\");

    fileOperate.createFile(fileName, targetPath);

    原以为没有问题,这样就可以先在读入的字符串中把"\"转换为"\\",然后在写入文本文件时就会写成"\",没想到,报如下错误:

    java.util.regex.PatternSyntaxException: Unexpected internal error near index 1

    \

    回来查了资料才发现,java的replaceAll函数,使用的是正则表达式作为转换依据,而"\"在正则表达式中也是特殊字符,最后,写成下面的代码才达到了我预想的目的:

    targetPath = targetPath.replaceAll("\\\\", "\\\\\\\\");

    fileOperate.createFile(fileName, targetPath);

    =====================================

    replace和replaceAll方法的区别:

    主要就是后者是基于规则表达多的替换,而前者是一般的基于字符或字符序列本身的替换。

    比如,可以通过replaceAll("\\d", "*")把一个字符串所有的数字字符都换成星号,replace就做不到,因为它不是基于规则表达多的替换。

    展开全文
  • 字符串replaceallIn this post, we will discuss the usage of another prevalent code constructions, the String.replaceAll and String.replace methods, and we will investigate how it affects the ...

    字符串replaceall

    In this post, we will discuss the usage of another prevalent code constructions, the String.replaceAll and String.replace methods, and we will investigate how it affects the performance of your code in Java 11 and what you can do about it.

    在本文中,我们将讨论另一个流行的代码构造的用法,即String.replaceAllString.replace方法,并且我们将研究它如何影响Java 11中代码的性能以及您可以如何做。

    (Please consider all the code below from the point of performance)

    (请从性能角度考虑以下所有代码)

    (Please don’t focus on numbers, they are just metrics to prove the point)

    (请不要专注于数字,它们只是证明这一点的指标)

    String.replaceAll (String.replaceAll)

    I wouldn’t say I like to make up the examples, so this time, we’ll start right away from the existing codebase of the Spring Framework. Let’s look at this line of the MetadataEncoder class of the spring-messaging module:

    我不会说我想组成示例,所以这次,我们将从Spring框架的现有代码库开始。 让我们看一下spring-messaging模块的MetadataEncoder类这一行

    value = value.contains(".") ? value.replaceAll("\\.","%2E") : value;

    Do you see what is wrong here?

    你看到这里有什么问题吗?

    All this code is trying to do is encode the dot symbol and pass the result later to the HTTP URL. I was very lucky to find that particular code snippet in the popular codebase. It has a few things in a single line.

    这些代码试图做的就是对符号进行编码,然后将结果传递给HTTP URL。 我很幸运在流行的代码库中找到了特定的代码段。 它在一行中有几件事。

    If you’re an experienced developer, you already know that the String.replaceAll method is using the regular expression pattern as the first parameter:

    如果您是一位经验丰富的开发人员,您已经知道String.replaceAll方法使用正则表达式模式作为第一个参数:

    public String replaceAll(String regex, String replacement) {
    return Pattern.compile(regex).matcher(this)
    .replaceAll(replacement);
    }

    However, in the above code, we replace only dot character. Very often, when you perform the replacement operation, you don’t need any pattern matching. You can just use another very similar and lighter method in terms of the performance — the String.replace:

    但是,在上面的代码中,我们仅替换了字符。 通常,执行替换操作时,不需要任何模式匹配。 就性能而言,您可以使用另一个非常相似且更轻松的方法-String.replace:

    public String replace(CharSequence target, CharSequence replacement)

    For example, when you need to replace a single word or a single character like in our example.

    例如,当您需要替换单个单词或单个字符(如我们的示例)时。

    Note: In Java 8 the String.replace method was using the Pattern inside as the String.replaceAll. However, since Java 9, it has changed. And that gives us a large room for optimizations in the existing codebase.

    注意:在Java 8中,String.replace方法使用内部的Pattern作为String.replaceAll。 但是,自Java 9以来,它已经发生了变化。 这为我们提供了在现有代码库中进行优化的广阔空间。

    Also, the usage of the methods String.replace and String.replaceAll seems like error-prone by design. That’s because when you start typing something in the IDE and you see both these methods closely, you might think that the String.replace replaces only the first occurrence while the replaceAll replaces all. And intuitively you will choose the String.replaceAll over the String.replace.

    同样,使用String.replaceString.replaceAll方法在设计上似乎容易出错。 这是因为当您开始在IDE中键入内容时,并且您同时看到这两种方法时,您可能会认为String.replace仅替换第一个匹配项,而replaceAll替换所有匹配项。 直观地,您将在String.replace上选择String.replaceAll

    Another interesting thing here is that the code above already has a micro-optimization, it’s the value.contains(“.”) method usage. So the string is checked for the dot symbol to avoid pattern matching if there is nothing to replace.

    另一个有趣的事情是,上面的代码已经进行了微优化,这就是value.contains(“。”)方法的用法。 因此,如果没有要替换的内容,则在字符串中检查符号,以避免模式匹配。

    Okay, let’s fix the example above:

    好的,让我们修复上面的示例:

    value = value.replace(".", "%2E");

    we can also try to apply the String.indexOf(“.”) optimization and check if that helps in the case of the String.replace method usage in Java 11:

    我们还可以尝试应用String.indexOf(“。”)优化,并检查在Java 11中使用String.replace方法是否有帮助:

    value = value.contains(".") ? value.replace(".", "%2E") : value;

    Let’s write the benchmark:

    让我们编写基准:

    Results (lower score means faster) :

    结果(分数越低意味着速度越快):

    It looks like usage of the String.indexOf(“.”) with the String.replaceAll method, in fact, makes sense, even for the empty input string, compiling and matching the pattern takes too much time. ~50x difference is huge. The same applies to the input string without any dot symbols. And when the actual replacement work had to be performed, the String.replace method outperforms the String.replaceAll by three times.

    实际上,将String.indexOf(“。”)String.replaceAll方法一起使用似乎很有意义,即使对于空的输入字符串,编译和匹配模式也要花费大量时间。 约50倍的差异是巨大的。 没有任何点符号的输入字符串也是如此。 而且,当必须执行实际的替换工作时, String.replace方法的性能要比 String.replaceAll高出三倍

    Also, it seems like the String.indexOf optimization doesn’t make any sense with the String.replace method in Java 11 anymore, while it was required in Java 8 when we had a pattern matching inside. Now it even makes it a bit slower. That’s because of the String.replace method implementation, as it already performs String.indexOf search inside. So we’re doing the double job here.

    同样,似乎String.indexOf优化对于Java 11中的String.replace方法不再具有任何意义,而当Java 8中具有模式匹配时,它在Java 8中是必需的。 现在,它甚至使它变慢了一点。 那是因为String.replace方法的实现,因为它已经在内部执行了String.indexOf搜索。 所以我们在这里做双重工作。

    “But you can precompile the regular pattern expression and use it in order to improve the performance of String.replaceAll method”, you would say. Agree. In fact, we do that a lot in Blynk.

    您会说:“但是您可以预编译正则模式表达式,并使用它来提高String.replaceAll方法的性能。” 同意。 实际上,我们在Blynk中做了很多事情

    Let’s check how precompiled pattern changes the numbers:

    让我们检查一下预编译模式如何改变数字:

    Results (lower score means faster) :

    结果(分数越低意味着速度越快):

    Yes, the numbers are better now. However, still not that good as in the case of the String.replace method. We can try to focus on optimizing the regular pattern even more, but there are already enough posts about it.

    是的,现在的数字更好了。 但是,仍然不如String.replace方法那样好。 我们可以尝试更多地专注于优化常规模式,但是已经有足够的帖子了。

    You might think that an initial example is just a single place, and it’s pretty rare. Let’s look into the GitHub:

    您可能会认为最初的示例只是一个地方,而且很少见。 让我们看一下GitHub:

    Image for post

    GitHub just indexed some repositories, and on the first screen, five out of the six String.replaceAll usages could be replaced with String.replace! Yes, many projects are still on Java 8, which won’t make any difference for them. However, after most developers migrate to Java 11, we’ll have a lot of the slow legacy code out there. We can start improving it right away.

    GitHub刚刚索引了一些存储库,在第一个屏幕上,六个String.replace中的五个都可以用String.replace替换! 是的,许多项目仍使用Java 8,这对他们没有任何影响。 但是,在大多数开发人员迁移到Java 11之后,我们将获得许多缓慢的旧代码。 我们可以立即开始对其进行改进。

    StringUtils.replace (StringUtils.replace)

    Before Java 11, when you had a hot path with the String.replace method, you had to find the faster alternatives in some 3-d party libraries or even write your own custom version. The most known 3-d party alternative is the Apache Commons StringUtils.replace method.

    在Java 11之前,当您使用String.replace方法获得热路径时,您必须在某些3-d方库中找到更快的替代方法,甚至编写自己的自定义版本。 最有名的3-d替代方法是Apache Commons StringUtils.replace方法。

    An example of a custom replace method could be found, for instance, in the Spring Framework. Here it is.

    自定义替换方法的示例可以在例如Spring Framework中找到。 在这里

    Let’s look at another Spring code snippet:

    让我们看一下另一个Spring 代码片段

    String internalName = StringUtils.replace(className, ".", "/");

    Do you see what is wrong here?

    你看到这里有什么问题吗?

    Let’s check Spring (latest source code), Apache Commons (latest version 3.11 of commons-lang3), and Java methods in our benchmark:

    让我们在基准测试中检查Spring(最新源代码),Apache Commons(commons-lang3的最新版本3.11)和Java方法:

    Results (lower score means faster) :

    结果(分数越低意味着速度越快):

    Hm, it looks like all methods are pretty close. Apache Commons is a bit slower, but that’s because it has additional logic for handling the case insensitive replacement. So everything makes sense.

    嗯,看来所有方法都差不多。 Apache Commons有点慢,但这是因为它具有用于处理区分大小写的替换的附加逻辑。 因此,一切都有意义。

    And now, as we have similar performance, we don’t need a custom method or 3-d party library anymore in order to perform the fast String.replace in Java 11.

    现在,由于我们具有类似的性能,因此不再需要自定义方法或3-d方库即可在Java 11中执行快速的String.replace

    But something still not ok with this line:

    但是,这行仍然不可行:

    return value.replace(".", "/");

    Do you see what is wrong here?

    你看到这里有什么问题吗?

    Contrary to the first example where actual string replacement happens, here we have a single character both for the search and replace. And as we know, Java has a specialized version for character replacement:

    与第一个示例实际发生字符串替换的情况相反,这里我们有一个用于搜索和替换的字符。 众所周知,Java有一个专门的字符替换版本:

    String replace(char oldChar, char newChar)

    Let’s add it to our benchmark as well:

    我们也将其添加到基准中:

    @Benchmark
    public String replaceChar() {
    return value.replace('.', '/');
    }

    Apache Commons library also has StringUtils.replaceChars, but it uses String.replace(char, char) inside, so we’ll skip it. And we are one more step closer to eliminate this 3-d party library from your project.

    Apache Commons库也具有StringUtils.replaceChars ,但是它在内部使用String.replace(char,char) ,因此我们将其跳过。 而且,从您的项目中删除此3-d方库还需要再走一步。

    Results (lower score means faster) :

    结果(分数越低意味着速度越快):

    Java character specialized version for the single char replacement four times faster than overloaded String.replace(String, String) and the custom Spring approach. The funny thing is that even in Java 8 String.replace(char, char) is optimized well enough. So Spring could safely use the String.replace(char, char).

    Java字符专用版本的单个字符替换比重载String.replace(String,String)和自定义Spring快四倍 方法。 有趣的是,即使在Java 8中, String.replace(char,char)的优化也足够好。 因此,Spring可以安全地使用String.replace(char,char)

    删除字符串 (String.remove)

    I hope you aren’t tired yet :)? Let’s look at this last code example:

    我希望你还不累:)? 让我们看一下最后的代码示例:

    value = value.replace(".", "");

    Do you see what is wrong here?

    你看到这里有什么问题吗?

    Unfortunately, Java still doesn’t have the String.remove method. As an alternative, we could use String.replace(char, char) method, but Java doesn’t have empty character literal as well, we can’t write code like that:

    不幸的是,Java仍然没有String.remove方法。 作为替代,我们可以使用String.replace(char,char)方法,但是Java也没有空字符文字,因此我们不能编写如下代码:

    value.replace('.', '');

    So, instead, we have to use a “hack” above.

    因此,我们必须在上面使用“ hack”。

    Fortunately, there are many 3-d party implementations out there like Apache Commons StringUtils.remove(String, char). Spring, for example, uses own custom implementation for that based on own custom replace method:

    幸运的是,那里有许多3-d第三方实现,例如Apache Commons StringUtils.remove(String,char) 。 例如,Spring使用基于自己的自定义替换方法的自定义实现:

    public static String delete(String inString, String pattern) {
    return StringUtils.replace(inString, pattern, "");
    }

    Let’s check Spring, Apache Commons, and Java methods in our benchmark again for the remove operation:

    让我们再次检查基准测试中的Spring,Apache Commons和Java方法是否进行了删除操作:

    Results (lower score means faster) :

    结果(分数越低意味着速度越快):

    Specialized Apache Commons version wins by almost three times. The interesting thing here is that even specialized and optimized char removal is slower than char replacement in the String.replace(char, char). There is definitely still room for even further improvement.

    专门的Apache Commons版本赢得了近三倍的胜利。 有趣的是,即使是专门优化的char删除也比String.replace(char,char)中的char替换要慢。 肯定还有进一步改进的空间。

    Hopefully, someday we’ll see that in Java.

    希望有一天,我们会在Java中看到它。

    结论 (Conclusions)

    • Use Java 11

      使用Java 11
    • Use the String.replace over the String.replaceAll when possible

      尽可能在String.replaceAll上使用S tring.replace

    • If you have to use the String.replaceAll, try to precompile the regular expression in the hot paths

      如果必须使用String.replaceAll ,请尝试在热路径中预编译正则表达式

    • Go with a specialized version of the String.replace(char, char) instead of the String.replace(String, String) when you can

      如果可以,请使用String.replace(char,char)的专用版本而不是String.replace(String,String)

    • For hot paths, you’ll still need to consider 3-d party libraries or custom methods instead of the String.replace(value, “”) code pattern

      对于热路径,您仍然需要考虑3-d方库或自定义方法,而不是String.replace(value,“”)代码模式

    Here is a source code of benchmarks so that you can try it yourself.

    这是基准测试的源代码 ,因此您可以自己尝试。

    Thank you for your attention, and stay tuned.

    感谢您的关注,敬请期待。

    Previous post: Micro optimizations in Java. Good, nice and slow Enum

    上一篇: Java中的微优化。 好,好,慢Enum

    翻译自: https://medium.com/javarevisited/micro-optimizations-in-java-string-replaceall-c6d0edf2ef6

    字符串replaceall

    展开全文
  • 在这篇文章中,我们将讨论另一种流行的代码结构String.replaceAll和String.replace方法的使用,我们将研究它如何影响 Java 11 中代码的性能以及您可以做些什么。 (请从性能的角度考虑以下所有代码) (请不要关注...

    在这篇文章中,我们将讨论另一种流行的代码结构String.replaceAllString.replace方法的使用,我们将研究它如何影响 Java 11 中代码的性能以及您可以做些什么。

    (请从性能的角度考虑以下所有代码)

    (请不要关注数字,它们只是证明这一点的指标)

    String.replaceAll

    我不会说我喜欢编造示例,所以这次,我们将从 Spring 框架的现有代码库开始。我们看一下spring-messaging模块的MetadataEncoder类这一行

    value.contains(".") ?value.replaceAll("\\.","%2E") :值;

    你知道这里有什么问题吗?

    这段代码试图做的就是对符号进行编码,然后将结果传递给 HTTP URL。我很幸运能在流行的代码库中找到那个特定的代码片段。它在一行中有几件事。

    如果您是一位经验丰富的开发人员,您已经知道String.replaceAll 方法使用正则表达式模式作为第一个参数:

    公共字符串替换所有(字符串正则表达式,字符串替换){
        返回模式。<em>编译</em>(正则表达式).matcher(this) 
                      .replaceAll(replacement); 
    }

    但是,在上面的代码中,我们只替换了字符。很多时候,当您执行替换操作时,您不需要任何模式匹配。就性能而言,您可以使用另一种非常相似且更轻的方法 - String.replace:

    公共字符串替换(CharSequence 目标,CharSequence 替换)

    例如,当您需要像我们的示例中那样替换单个单词或单个字符时。

    注意:在 Java 8 中,String.replace方法 使用里面的Pattern作为String.replaceAll。但是,自 Java 9 以来,它发生了变化。这为我们在现有代码库中提供了很大的优化空间。

    此外,String.replaceString.replaceAll方法的使用在设计上似乎很容易出错。这是因为当您开始在 IDE 中输入内容并仔细查看这两种方法时,您可能会认为String.replace仅替换第一个匹配项,而replaceAll替换所有匹配项。直观地,您将选择String.replaceAll而不是String.replace

    另一个有趣的地方是上面的代码已经有了一个微优化,就是value.contains(“.”)方法的使用。因此,如果没有可替换的内容,则会检查字符串中的符号以避免模式匹配。

    好的,让我们修复上面的示例:

     value.replace(".", "%2E");

    我们还可以尝试应用String.indexOf(“.”)优化并检查这是否有助于Java 11 中使用String.replace方法:

     value.contains(".") ?value.replace(".", "%2E") : 值;

    让我们编写基准测试:

    @BenchmarkMode(Mode.AverageTime)
    @Fork(1)
    @State(Scope.Thread)
    @Warmup(iterations = 5, time = 1)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Measurement(iterations = 10, time = 1)
    public class ReplaceAll {
    
        @Param({"", "somePathNoDoT", "some.Path.With.Dot"})
        String value;
    
        @Benchmark
        public String replaceAllWithContains() {
            return value.contains(".") ? value.replaceAll("\\.", "%2E") : value;
        }
    
        @Benchmark
        public String replaceAll() {
            return value.replaceAll("\\.", "%2E");
        }
    
        @Benchmark
        public String replace() {
            return value.replace(".", "%2E");
        }
    
        @Benchmark
        public String replaceWithContains() {
            return value.contains(".") ? value.replace(".", "%2E") : value;
        }
    
    }
    

    结果(分数越低意味着越快):

    JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
    
    ```
    Benchmark                                     (value)  Mode  Cnt    Score    Error  Units
    ReplaceAll.replace                                     avgt   10    3.836 ±  0.060  ns/op
    ReplaceAll.replaceAll                                  avgt   10  147.857 ±  1.550  ns/op
    ReplaceAll.replaceAllWithContains                      avgt   10    3.777 ±  0.069  ns/op
    ReplaceAll.replaceWithContains                         avgt   10    3.778 ±  0.075  ns/op
    
    ReplaceAll.replace                      somePathNoDoT  avgt   10    7.647 ±  0.646  ns/op
    ReplaceAll.replaceAll                   somePathNoDoT  avgt   10  156.495 ±  1.751  ns/op
    ReplaceAll.replaceAllWithContains       somePathNoDoT  avgt   10    7.640 ±  0.291  ns/op
    ReplaceAll.replaceWithContains          somePathNoDoT  avgt   10    7.545 ±  0.298  ns/op
    
    ReplaceAll.replace                 some.Path.With.Dot  avgt   10  123.856 ±  1.686  ns/op
    ReplaceAll.replaceAll              some.Path.With.Dot  avgt   10  389.632 ± 18.308  ns/op
    ReplaceAll.replaceAllWithContains  some.Path.With.Dot  avgt   10  378.527 ±  6.434  ns/op
    ReplaceAll.replaceWithContains     some.Path.With.Dot  avgt   10  126.918 ±  0.940  ns/op
    ```

    看起来String.indexOf(“.”)String.replaceAll方法一起使用,实际上是有道理的,即使对于空输入字符串,编译和匹配模式也需要太多时间。约 50 倍的差异是巨大的。这同样适用于没有任何点符号的输入字符串。而当必须执行实际的替换工作时,String.replace方法的性能比String.replaceAll 高出三倍

    此外,似乎String.indexOf优化对Java 11 中的String.replace方法没有任何意义,而在 Java 8 中当我们内部有模式匹配时需要它。现在它甚至让它变慢了一点。这是因为String.replace方法的实现,因为它已经在里面执行了String.indexOf搜索。所以我们在这里做双重工作。

    “但是你可以预编译正则模式表达式并使用它来提高String.replaceAll方法的性能”,你会说。同意。事实上,我们在Blynk经常这样做。

    让我们检查预编译模式如何更改数字:

    @BenchmarkMode(Mode.AverageTime)
    @Fork(1)
    @State(Scope.Thread)
    @Warmup(iterations = 5, time = 1)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Measurement(iterations = 10, time = 1)
    public class ReplaceAllPrecompiled {
    
        @Param({"", "somePathNoDoT", "some.Path.With.Dot"})
        String value;
        private static final Pattern DOT_PATTERN = Pattern.compile("\\.");
    
        @Benchmark
        public String replaceAllWithPrecompiled() {
            return DOT_PATTERN.matcher(value).replaceAll("%2E");
        }
    
    }

    结果(分数越低意味着越快):

    JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
    
    ```
    Benchmark                         (value)  Mode  Cnt    Score    Error  Units
    replace                                    avgt   10    3.843 ±  0.100  ns/op
    replace                     somePathNoDoT  avgt   10    8.693 ±  0.693  ns/op
    replace                some.Path.With.Dot  avgt   10  127.022 ±  8.842  ns/op
    
    replaceAll                                 avgt   10  156.550 ± 10.741  ns/op
    replaceAll                  somePathNoDoT  avgt   10  159.619 ±  4.654  ns/op
    replaceAll             some.Path.With.Dot  avgt   10  391.912 ± 11.445  ns/op
    
    replaceAllPrecompiled                      avgt   10   52.466 ±  0.791  ns/op
    replaceAllPrecompiled       somePathNoDoT  avgt   10   64.337 ±  0.854  ns/op
    replaceAllPrecompiled  some.Path.With.Dot  avgt   10  274.867 ±  3.535  ns/op

    是的,现在数字好多了。但是,仍然不如String.replace方法那么好。我们可以尝试更多地专注于优化正则模式,但是关于它的帖子已经足够多。

    您可能会认为最初的示例只是一个地方,而且非常罕见。让我们看看 GitHub:

    GitHub 刚刚索引了一些存储库,在第一个屏幕上,六个String.replaceAll用法中有五个可以替换为String.replace!是的,许多项目仍在使用 Java 8,这对它们没有任何影响。但是,在大多数开发人员迁移到 Java 11 之后,我们将有很多缓慢的遗留代码。我们可以立即开始改进它。

    StringUtils.replace

    在 Java 11 之前,当您有使用String.replace方法的热门路径时,您必须在一些 3-d 方库中找到更快的替代方案,甚至编写自己的自定义版本。最著名的 3-d 方替代方案是 Apache Commons StringUtils.replace方法。

    例如,可以在 Spring 框架中找到自定义替换方法的示例。在这里

    让我们看另一个 Spring代码片段

    字符串内部名称 = StringUtils 替换(类名,“。”,“/”);

    你知道这里有什么问题吗?

    让我们在基准测试中检查 Spring(最新源代码)、Apache Commons(commons-lang3 的最新版本 3.11)和 Java 方法:

    @BenchmarkMode(Mode.AverageTime)
    @Fork(1)
    @State(Scope.Thread)
    @Warmup(iterations = 5, time = 1)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Measurement(iterations = 10, time = 1)
    public class ReplaceCustom {
    
        @Param({"", "somePathNoDoT", "some.Path.With.Dot"})
        String value;
    
        @Benchmark
        public String replace() {
            return value.replace(".", "/");
        }
    
        @Benchmark
        public String replaceSpring() {
            return springReplace(value, ".", "/");
        }
    
        @Benchmark
        public String replaceApache() {
            return StringUtils.replace(value, ".", "/");
        }
    }

    结果(分数越低意味着越快):

    JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
    
    ```
    Benchmark                                     (value)  Mode  Cnt    Score   Error  Units
    ReplaceCustom.replace                                  avgt   10    4.497 ± 1.085  ns/op
    ReplaceCustom.replace                   somePathNoDoT  avgt   10    7.944 ± 0.289  ns/op
    ReplaceCustom.replace              some.Path.With.Dot  avgt   10  106.270 ± 5.095  ns/op
    
    ReplaceCustom.replaceApache                            avgt   10    3.784 ± 0.065  ns/op
    ReplaceCustom.replaceApache             somePathNoDoT  avgt   10    8.168 ± 0.052  ns/op
    ReplaceCustom.replaceApache        some.Path.With.Dot  avgt   10  121.248 ± 1.935  ns/op
    
    ReplaceCustom.springCustomReplace                      avgt   10    3.628 ± 0.058  ns/op
    ReplaceCustom.springCustomReplace       somePathNoDoT  avgt   10    7.991 ± 0.268  ns/op
    ReplaceCustom.springCustomReplace  some.Path.With.Dot  avgt   10  108.191 ± 6.138  ns/op

    嗯,看起来所有方法都非常接近。Apache Commons 有点慢,但那是因为它有额外的逻辑来处理不区分大小写的替换。所以一切都是有道理的。

    现在,由于我们具有相似的性能,我们不再需要自定义方法或 3-d 方库来执行Java 11 中的快速String.replace

    但是这条线还是不行:

    返回值.replace(".", "/");

    你知道这里有什么问题吗?

    与发生实际字符串替换的第一个示例相反,这里我们有一个用于搜索和替换的字符。众所周知,Java 有一个专门的字符替换版本:

    字符串替换(char oldChar, char newChar)

    让我们也将它添加到我们的基准测试中:

    @Benchmark 
    public String replaceChar() { 
        return value.replace('.', '/'); 
    }

    Apache Commons 库也有StringUtils.replaceChars,但它在内部使用String.replace(char, char),所以我们将跳过它。我们离从您的项目中消除这个 3-d 派对库更近了一步。

    结果(分数越低意味着越快):

    JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
    
    ```
    Benchmark                                     (value)  Mode  Cnt    Score   Error  Units
    ReplaceCustom.replace                                  avgt   10    4.497 ± 1.085  ns/op
    ReplaceCustom.replace                   somePathNoDoT  avgt   10    7.944 ± 0.289  ns/op
    ReplaceCustom.replace              some.Path.With.Dot  avgt   10  106.270 ± 5.095  ns/op
    
    ReplaceCustom.replaceChar                              avgt   10    3.689 ± 0.040  ns/op
    ReplaceCustom.replaceChar               somePathNoDoT  avgt   10    8.787 ± 0.119  ns/op
    ReplaceCustom.replaceChar          some.Path.With.Dot  avgt   10   26.824 ± 0.391  ns/op
    
    ReplaceCustom.springCustomReplace                      avgt   10    3.628 ± 0.058  ns/op
    ReplaceCustom.springCustomReplace       somePathNoDoT  avgt   10    7.991 ± 0.268  ns/op
    ReplaceCustom.springCustomReplace  some.Path.With.Dot  avgt   10  108.191 ± 6.138  ns/op

    用于单个字符替换的 Java 字符专用版本比重载的String.replace(String, String)和自定义 Spring方法快四倍。有趣的是,即使在 Java 8 中,String.replace(char, char)的优化也足够好。所以 Spring 可以安全地使用String.replace(char, char)

    字符串.remove

    我希望你还不累:)?让我们看一下最后一个代码示例:

     value.replace(".", "");

    你知道这里有什么问题吗?

    不幸的是,Java 仍然没有String.remove方法。作为替代方案,我们可以使用String.replace(char, char)方法,但 Java 也没有空字符文字,我们不能编写这样的代码:

    value.replace('.', '');

    所以,相反,我们必须使用上面的“hack”。

    幸运的是,有许多 3-d 方实现,例如 Apache Commons StringUtils.remove(String, char)。例如,Spring 使用自己的自定义实现,基于自己的自定义替换方法:

    public static String delete(String inString, String pattern) { 
       return StringUtils. <em>替换</em>(inString,模式,“”);
    }

    让我们再次检查我们的基准测试中的 Spring、Apache Commons 和 Java 方法以进行删除操作:

    @BenchmarkMode(Mode.AverageTime)
    @Fork(1)
    @State(Scope.Thread)
    @Warmup(iterations = 5, time = 1)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Measurement(iterations = 10, time = 1)
    public class RemoveChar {
    
        @Param({"", "somePathNoDoT", "some.Path.With.Dot"})
        String value;
    
        @Benchmark
        public String remove() {
            return value.replace(".", "");
        }
    
        @Benchmark
        public String removeApache() {
            return StringUtils.remove(value, '.');
        }
    
        @Benchmark
        public String removeSpring() {
            return springDelete(value, ".");
        }   
    }

    结果(分数越低意味着越快):

    JDK 11.0.8, OpenJDK 64-Bit Server VM, 11.0.8+10
    
    ```
    Benchmark                           (value)  Mode  Cnt   Score   Error  Units
    RemoveChar.remove                            avgt   10   4.405 ± 1.646  ns/op
    RemoveChar.remove             somePathNoDoT  avgt   10   7.820 ± 0.296  ns/op
    RemoveChar.remove        some.Path.With.Dot  avgt   10  92.185 ± 3.752  ns/op
    
    RemoveChar.removeApache                      avgt   10   3.708 ± 0.070  ns/op
    RemoveChar.removeApache       somePathNoDoT  avgt   10  10.018 ± 0.103  ns/op
    RemoveChar.removeApache  some.Path.With.Dot  avgt   10  37.822 ± 0.486  ns/op
    
    RemoveChar.removeSpring                      avgt   10   3.609 ± 0.033  ns/op
    RemoveChar.removeSpring       somePathNoDoT  avgt   10   7.996 ± 0.308  ns/op
    RemoveChar.removeSpring  some.Path.With.Dot  avgt   10  87.148 ± 1.391  ns/op
    ```

    专门的 Apache Commons 版本几乎了三倍。这里有趣的是,即使是专门和优化的 char 删除也比String.replace(char, char)中的 char 替换要慢。肯定还有进一步改进的空间。

    希望有一天我们会在 Java 中看到这一点。

    结论

    • 使用 Java 11
    • 尽可能在String.replaceAll 上使用 S string.replace
    • 如果必须使用String.replaceAll,请尝试在热路径中预编译正则表达式
    • 用的专门版本,请与string.replace(字符,字符),而不是与string.replace(字符串,字符串)时,你可以
    • 对于热路径,您仍然需要考虑 3-d 方库或自定义方法,而不是String.replace(value, “”)代码模式

    这是基准测试的源代码,您可以自己尝试。

    感谢您的关注,敬请期待。

    展开全文
  • .replaceAll is not a function nodejs14不可用 replaceAll 最近写了个 Nodejs 的后台,在本地跑的好好的,布到服务器上之后就提示这个信息: 原因 找了半天,原因是因为 replaceAll 是在 nodejs15 之后才加入的, ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 114,643
精华内容 45,857
关键字:

replaceall

友情链接: fxcbultimo.zip