How to know if JavaScript string.replace() did anything?

前端 未结 8 1850
盖世英雄少女心
盖世英雄少女心 2021-02-06 21:37

The replace function returns the new string with the replaces, but if there weren\'t any words to replace, then the original string is returned. Is there a way to k

相关标签:
8条回答
  • 2021-02-06 22:08

    Use .test()

    const regex = /foo/;
    const yourString = 'foo bar';
    
    if (regex.test(yourString)) {
      console.log('yourString contains regex');
    }
    

    The test() method executes a search for a match between a regular expression and a specified string. Returns true or false.

    0 讨论(0)
  • 2021-02-06 22:12

    A simple option is to check for matches before you replace:

    var regex = /i/g;
    var newStr = str;
    
    var replaced = str.search(regex) >= 0;
    if(replaced){
        newStr = newStr.replace(regex, '!');
    }
    

    If you don't want that either, you can abuse the replace callback to achieve that in a single pass:

    var replaced = false;
    var newStr = str.replace(/i/g, function(token){replaced = true; return '!';});
    
    0 讨论(0)
  • 2021-02-06 22:15

    With indexOf you can check wether a string contains another string.
    Seems like you might want to use that.

    0 讨论(0)
  • 2021-02-06 22:18

    Javascript replace is defected by design. Why? It has no compatibility with string replacement in callback.

    For example:

    "ab".replace(/(a)(b)/, "$1$2")
    > "ab"
    

    We want to verify that replace is done in single pass. I was imagine something like:

    "ab".replace(/(a)(b)/, "$1$2", function replacing() { console.log('ok'); })
    > "ab"
    

    Real variant:

    "ab".replace(/(a)(b)/, function replacing() {
      console.log('ok');
      return "$1$2";
    })
    
    > ok
    > "$1$2"
    

    But function replacing is designed to receive $0, $1, $2, offset, string and we have to fight with replacement "$1$2". The solution is:

    "ab".replace(/(a)(b)/, function replacing() {
      console.log('ok');
      // arguments are $0, $1, ..., offset, string
      return Array.from(arguments).slice(1, -2)
      .reduce(function (pattern, match, index) {
        // '$1' from strings like '$11 $12' shouldn't be replaced.
        return pattern.replace(
          new RegExp("\\$" + (index + 1) + "(?=[^\\d]|$)", "g"),
          match
        );
      }, "$1$2");
    });
    
    > ok
    > "ab"
    

    This solution is not perfect. String replacement itself has its own WATs. For example:

    "a".replace(/(a)/, "$01")
    > "a"
    
    "a".replace(/(a)/, "$001")
    > "$001"
    

    If you want to care about compatibility you have to read spec and implement all its craziness.

    0 讨论(0)
  • 2021-02-06 22:21

    Comparing the before and after strings is the easiest way to check if it did anything, there's no intrinsic support in String.replace().

    [contrived example of how '==' might fail deleted because it was wrong]

    0 讨论(0)
  • 2021-02-06 22:23

    If your replace has a different length from the searched text, you can check the length of the string before and after. I know, this is a partial response, valid only on a subset of the problem.

    OR

    You can do a search. If the search is successfull you do a replace on the substring starting with the found index and then recompose the string. This could be slower because you are generating 3 strings instead of 2.

    var test = "Hellllo";
    var index = test.search(/ll/);
    
    if (index >= 0) {
        test = test.substr(0, index - 1) + test.substr(index).replace(/ll/g, "tt");
    }
    
    alert(test);
    
    0 讨论(0)
提交回复
热议问题