String.Replace 仅替换第一次出现的匹配字符串。如何替换 *all* 出现?

Posted

技术标签:

【中文标题】String.Replace 仅替换第一次出现的匹配字符串。如何替换 *all* 出现?【英文标题】:String.Replace only replaces first occurrence of matched string. How to replace *all* occurrences? 【发布时间】:2016-09-08 21:38:14 【问题描述】:

来自其他编程语言,String.replace() 通常替换所有匹配字符串的出现。但是,javascript/typescript 并非如此。我在网上找到了许多使用正则表达式的 javascript 解决方案。由于特殊字符,我立即遇到了这个解决方案的问题。我怀疑有一种方法可以用正则表达式纠正这个问题,但我不是正则表达式专家。正如许多人在我之前所做的那样,我创建了自己的方法。

也许有一些方法可以通过使用自定义StringBuilder() 类来提高性能。我欢迎任何想法。

public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) 
    //
    // if invalid data, return the original string
    //
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0) )
        return (originalString);
    //
    // do text replacement
    //
    var dest = "";        
    var source: string = originalString;
    if (ignoreCase) 
    
        source = source.toLocaleLowerCase();
        oldValue = oldValue.toLowerCase();
    
    //
    // find first match
    //
    var StartPos = 0;
    var EndPos = source.indexOf(oldValue, StartPos);
    var Skip = (EndPos >= 0) ? EndPos - StartPos : source.length-StartPos;   
    //
    // while we found a matched string
    //     
    while (EndPos > -1) 
        //
        // copy original string skipped segment
        //
        if (Skip > 0) dest += originalString.substr(StartPos, Skip);            
        //
        // copy new value
        //
        dest += newValue;
        //
        // skip over old value
        //
        StartPos = EndPos + oldValue.length;
        //
        // find next match
        //
        EndPos = source.indexOf(oldValue, StartPos);
        Skip = (EndPos >= 0) ? EndPos - StartPos : source.length - StartPos;    
    
    //
    // append the last skipped string segment from original string
    //
    if (Skip > 0) dest += originalString.substr(StartPos, Skip);   

    return dest;

为了向string 类添加对该方法的支持,我添加了以下代码:

interface String  EZReplace(oldValue: string, newValue: string, ignorCase?: boolean): string; 

String.prototype.EZReplace = function (oldValue: string, newValue: string, ignorCase: boolean = false) 
return EZUtil.Replace(this, oldValue, newValue, ignorCase);

....重新查看其他帖子后,我将代码修改为使用正则表达式。执行性能测试会很有趣。

 public static Replace = function (originalString: string, oldValue: string, newValue: string, ignoreCase: boolean = false) 
    //
    // if invalid data, return the original string
    //
    if ((originalString == null) || (oldValue == null) || (newValue == null) || (oldValue.length == 0))
        return (originalString);
    //
    // set search/replace flags
    //
    var Flags: string = (ignoreCase) ? "gi" : "g";
    //
    // apply regex escape sequence on pattern (oldValue)
    //
    var pattern = oldValue.replace(/[-\[\]\/\\\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
    //
    // replace oldValue with newValue
    //
    var str = originalString.replace(new RegExp(pattern, Flags), newValue);
    return (str);

【问题讨论】:

你已经看过这篇文章了吗? ***.com/questions/1144783/… 是的,等等。但是,在重新审视它之后,我对如何使用正则表达式有了更好的理解。我修改了上面的代码以反映它。对我来说,这是一个更简洁的答案。也许它可以帮助其他人。 【参考方案1】:

就我而言,我使用的是 Node 12+。并且节点没有.replaceAll()(检查Browser Compatibility on MDN)。

但我的解决方案是使用带有 .replace() 的 Regex(/g)。关键是使用/g

const s = `[People,Contracts,Facilities]`;
// My case was to remove the `[` and `]`
// So the key is using `/g`
const res = s.replace(/\[/g, '').replace(/\]/g, '');

【讨论】:

【参考方案2】:

在我的例子中,我确实在 TypeScript 中这样做了。

this.mystr= this.mystr.replace(new RegExp('class="dec-table"', 'g'), 'class="copydec-table"');

感谢How to replace all occurrences of a string in JavaScript?

【讨论】:

【参考方案3】:

在打字稿中,String.Replace 仅替换第一次出现的匹配字符串。需要 String.replaceAll() 方法

这里的 TypeScript 没有什么特别之处 (after all TypeScript is just JavaScript with type annotations)。 JavaScript string.replace 仅在给定字符串时替换第一个实例。获得全部替换的唯一方法是使用 regex/g 修饰符。

或者我只是这样做:

somestring.split('oldString').join('newString');

【讨论】:

是的,String.split().join() 方法又短又甜。但是,无法执行不区分大小写的搜索/替换。我第一次使用带有 /g 修饰符的正则表达式时,它在代码执行期间为正则表达式生成了一个无效的模式。我需要在模式中包含转义序列。 var pattern = oldValue.replace(/[-\[\]\/\\\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); 这就是为什么我喜欢在我的示例中包含整个函数。该过程简单而简短,足以允许。 喜欢拆分连接的东西! 作为参考,这里使用正则表达式的 TypeScript 替换调用:myString.replace(/oldString/g, 'newString); 当您必须替换特殊字符('[', ']')时,正则表达式会失败 @JohanAspeling 它不必失败。您可以随时转义特殊字符,例如 ( '\[', '\]' )

以上是关于String.Replace 仅替换第一次出现的匹配字符串。如何替换 *all* 出现?的主要内容,如果未能解决你的问题,请参考以下文章

9 个功能强大的 JavaScript 技巧

JAVA中string.replace()和string.replaceAll()的区别及用法

JAVA中string.replace和string.replaceAll的区别及用法

JAVA中string.replace和string.replaceAll的区别及用法

Javascript字符串替换(所有出现)

仅替换第一次出现的字符串?