Replacing multiple patterns in a block of data

后端 未结 4 677
遇见更好的自我
遇见更好的自我 2020-12-31 14:48

I need to find the most efficient way of matching multiple regular expressions on a single block of text. To give an example of what I need, consider a block of text:

<
相关标签:
4条回答
  • 2020-12-31 15:11

    An improved answer:

    var index = {
        'Hello': 'Bye',
        'World': 'Universe'
    };
    
    var pattern = '';
    for (var i in index) {
        if (pattern != '') pattern += '|';
        pattern += i;
    }
    
    var text = "Hello World what a beautiful day";
    text.replace(new RegExp(pattern, 'g'), function($0) {
        return index[$0] != undefined ? index[$0] : $0;
    });
    
    0 讨论(0)
  • 2020-12-31 15:25

    Edit

    6 years after my original answer (below) I would solve this problem differently

    function mreplace (replacements, str) {
      let result = str;
      for (let [x, y] of replacements)
        result = result.replace(x, y);
      return result;
    }
    
    let input = 'Hello World what a beautiful day';
    
    let output = mreplace ([
      [/Hello/, 'Bye'],
      [/World/, 'Universe']
    ], input);
    
    console.log(output);
    // "Bye Universe what a beautiful day"

    This has as tremendous advantage over the previous answer which required you to write each match twice. It also gives you individual control over each match. For example:

    function mreplace (replacements, str) {
      let result = str;
      for (let [x, y] of replacements)
        result = result.replace(x, y);
      return result;
    }
    
    let input = 'Hello World what a beautiful day';
    
    let output = mreplace ([
      //replace static strings
      ['day', 'night'],
      // use regexp and flags where you want them: replace all vowels with nothing
      [/[aeiou]/g, ''],
      // use captures and callbacks! replace first capital letter with lowercase 
      [/([A-Z])/, $0 => $0.toLowerCase()]
    
    ], input);
    
    console.log(output);
    // "hll Wrld wht  btfl nght"


    Original answer

    Andy E's answer can be modified to make adding replacement definitions easier.

    var text = "Hello World what a beautiful day";
    text.replace(/(Hello|World)/g, function ($0){
      var index = {
        'Hello': 'Bye',
        'World': 'Universe'
      };
      return index[$0] != undefined ? index[$0] : $0;
    });
    
    // "Bye Universe what a beautiful day";
    
    0 讨论(0)
  • 2020-12-31 15:28

    You can pass a function to replace:

    var hello = "Hello World what a beautiful day";
    hello.replace(/Hello|World/g, function ($0, $1, $2) // $3, $4... $n for captures
    {
        if ($0 == "Hello")
            return "Bye";
        else if ($0 == "World")
            return "Universe";
    });
    
    // Output: "Bye Universe what a beautiful day";
    
    0 讨论(0)
  • 2020-12-31 15:30

    If the question is how to replace multiple generic patterns with corresponding replacements - either strings or functions, it's quite tricky because of special characters, capturing groups and backreference matching.

    You can use https://www.npmjs.com/package/union-replacer for this exact purpose. It is basically a string.replace(regexp, string|function) counterpart, which allows multiple replaces to happen in one pass while preserving full power of string.replace(...).

    Disclosure: I am the author and the library was developed because we had to support user-configured replaces.

    0 讨论(0)
提交回复
热议问题