A simple requirement in a recent project was to put a paragraph in the following format

ABC {1220}cde{2222}def{CCCC} ABC {1}cde{2}def{3} ABC {1220}cde{2222}def{CCCC} ABC {1}cde{2}def{3}

Rough solution

Well, this is a simple problem, let a new friend to do it, the result of his code looks like this

var left = "{",right = "}"; Then write code again and again to find the content of the match, I will not paste the specific codeCopy the code

Seeing this, I was devastated inside. Didn’t you learn regular expressions? He said he had. He said he had, he said he had…

The first regular expression

The junior partner from the idea of regular expression to solve, and then come up with a regular expression like this.

var matchs = text.match(/\{.*\}/g); for(var i = 0; i < matchs.length; i ++){ text = text.replace(matchs[i],"{"+(i+1)+"}") }Copy the code

But it didn’t turn out right. It turned out like this:

var text = "aaa{111}{bbb}{111}"; var matchs = text.match(/\{.*\}/g); for(var i = 0; i < matchs.length; I + +) {text = text. Replace (matchs [I], "{}" + (I + 1) + "")} the end result is like this: aaa {1}Copy the code

Second regular expression

The problem with the first expression is that it starts with the laziness and greed of regular expressions. Here’s how:

When a regular expression contains a qualifier that accepts repetition, the common behavior is to match as many characters as possible (without matching the entire expression). Take this expression: a.b, which will match the longest string that starts with a and ends with B. If you use it to search for aabab, it matches the entire string aabab. This is called greedy matching. Sometimes, we need lazy matching, which means matching as few characters as possible. Any qualifier given above can be converted to lazy matching by adding a question mark after it. . So.? This means matching any number of duplicates, but using the fewest duplicates to make the whole match successful.

It can be seen that the greedy mode is used in this example, so the matching result is like this:

{111}{bbb}{111}
Copy the code

To improve the program, all you have to do is change greed mode to lazy mode, and as I said, just put a question mark after it, right? So the improved version looks like this:

var text = "aaa{111}bbb{111}"; var matchs = text.match(/\{.*\}/g); for(var i = 0; i < matchs.length; I + +) {text = text. Replace (matchs [I], "{}" + (I + 1) + "")} the end result is right: aaa {1} BBB {2}Copy the code

The replace function

The second regular expression above will do the trick, but the code is longer. In fact, the second parameter of replace can be used directly to specify the function function. The code is much less, as follows:

var text = "aaa{111}bbb{111}"; var index = 1; text = text.replace(/\{.*? \}/g,function(){ return "{" + (index ++) + "}" })Copy the code

subsequent

Of course, the solution in this case does not take into account the mismatched parentheses, but the related case is a little more complicated, so think for yourself.

To learn regular expressions, newcomers can refer to a document I read a few years ago, which is quite detailed.

Deerchao.net/tutorials/r…