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

前端 未结 8 1849
盖世英雄少女心
盖世英雄少女心 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: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.

提交回复
热议问题