Hans Hansen
Hans Hansen

Reputation: 49

Replace all occurrences of a string no matter how different it written

I'm trying to see if this can be accomplished in plain and pure JavaScript.

Lets say I have a string :

var ourstring = "Blah TEST ('1')  TEST('2') Blah BLah TEST ( '1' )  TEST( '2' )";

Please pay attention to how different TEST('1') is written inside the string.

How can we detect all TEST('') inside the string no matter how different it written and replace them with something else based on the contain of the parenthesis.

So TEST ('1') become TEST('1.node') instead. Is that possible if yes, please show me and explain step by step so i can learn from it.

I have searched for such solution, but could not find anything. The problem I don't know how to do that. Please show me.

Upvotes: 0

Views: 78

Answers (3)

Sam
Sam

Reputation: 38

What you're looking for is a regex replace. You need to write a regular expression which will match the text that you want to change and then use it with String.replace.

var newString = ourString.replace(/(TEST\('\d+)('\))/gi, function(match, group1, group2) {
   return group1+'.node'+group2;
});

The important part of that is the regex: (TEST('\d+)('))

This matches the TEST followed by brackets, quotes and one or more digits, then closing quotes and brackets. It puts the first part (e.g. TEST('1) into a capturing group and then does the same with the second part (')).

These should end up in the group1 and group2 variables. Then the function is just stitching these back together again with your extra .node in the middle.

edit

You could just capture the number and then decide what to return based on that:

var newString = ourString.replace(/TEST\('(\d+)'\)/gi, function(match, num) {
   if(num == '1')
        return "TEST('1.node')";
   else
        return "TEST('1.otherThing')";
});

The thing to look at in the regex is that there are literal brackets which match what is in your string \( and there are capturing groups (which are the unescaped brackets).

Upvotes: 0

Ele
Ele

Reputation: 33726

This regex /(TEST)\s*\((\s*)'([\d]?)'(\s*)\)/g captures five groups:

  1. Word TEST
  2. Spaces between TEST and the first (
  3. Spaces between ' and the inner number.
  4. The inner number.
  5. Spaces between ' and the last ).

With those five groups, you can build the exact structure + the word node.

var ourstring = "Blah TEST ('1')  TEST('2') Blah BLah TEST (      '1' )  TEST( '2'      )";
console.log(ourstring.replace(/(TEST)(\s*)\((\s*)'([\d])'(\s*)\)/g, "$1$2($3'$4.node'$5)"))
.as-console-wrapper { max-height: 100% !important; top: 0; }

This approach is for checking the captured group to make a decision about the desired value to be replaced.

var ourstring = "Blah TEST ('1')  TEST('2') Blah BLah TEST (      '1' )  TEST( '2'      )";
console.log(ourstring.replace(/'([\d])'/g, function(match, group) {
  if (group === '1') {
    return `'${group}.nodeOne'`;
  }
  
  if (group === '2') {
    return `'${group}.nodeTwo'`;
  }
}))
.as-console-wrapper { max-height: 100% !important; top: 0; }

Upvotes: 1

treyhakanson
treyhakanson

Reputation: 4911

Use a regular expression:

    let str = "TEST ('1')  TEST('2') Blah BLah TEST ( '1' )  TEST( '2' )";
    const re = /TEST\s*\(\s*'([\d]*?)'\s*\)/g;
    str = str.replace(re, "TEST('$1.node')");
    console.log(str)
    /* str becomes:
       "TEST('1.node')  TEST('2.node') Blah BLah TEST('1.node')  TEST('2.node')"
    */

breaking down the regex step by step:

  1. TEST to match the text exactly
  2. \s? means optional whitespace; \s signifies any whitespace character, ? signifies optional
  3. \( to match parenthesis; it must be escaped since ( relates to grouping in regular expressions
  4. ([\d]*) matches the characters between [] (in this case just digits, \d) 0-many times. Since it is between (), this value will be selected as a match group, and be available as $1 in the replace string
  5. g at the end is for greedy, meaning match as many times as possible in the given string

Depending on what you're going for, you way want to replace the optional (?) after whitespace with * to signify 0-many whitespace characters.

Upvotes: 2

Related Questions