简体   繁体   中英

Regex: limited symbols between square brackets

String sample: Text sample [79zd915j][fxC1bPYW][asd12233]

As result I want to have an array: ["[79bl9F5j]", "[fKCebPYW]", "[asd12233]"]

I made solution, but somehow in doesn't stop after 8 symbols inside brackets and goes to the end of string.

My regex: /(\\[[\\w\\d]{8}\\])+/.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]")

My result: ["[79bl9F5j][fKCebPYW][asd12233]", "[asd12233]"]

Help me to write correct one and tell me please what is wrong with my regex? Why it doesn't work like I expected?

(\[\w{8}\])

is enough.See demo.

https://regex101.com/r/xvY9D9/1

the + sign is causing the trouble.It will match the whole [79zd915j][fxC1bPYW][asd12233] but capture only the last [asd12233] in group 1 as regex engine remembers only the last group when consecutive groups are being matched

The first problem is + . That means a repeat of one ore more times from what is before. So this would match:

[abcdefgh] and [abcdefgh][abcdefgh] and [abcdefgh][abcdefgh][abcdefgh] ...

For example

 var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]"; var regex = /(\\[[\\w\\d]{8}\\])+/; var res = regex.exec(str); console.log(res[0]); 

But you won't match it together, you want match it separate !

The second problem is that exec() even with a global flag will output only the first occurrence :

 var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]"; var regex = /(\\[[\\w\\d]{8}\\])/g; var res = regex.exec(str); console.log(res[0]); 

So in this case use match() without a + and with a global flag:

 var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]"; var regex = /(\\[[\\w\\d]{8}\\])/g; var res = str.match(regex); console.log(res); 

More information about regular expression .

TL;DR → use String.match() instead of RegExp.exec()


Your pattern /(\\[[\\w\\d]{8}\\])+/ can be simplified first, because the pre-defined \\w is [A-Za-z0-9_] and that already contains everything in \\d - so we simplify to /(\\[\\w{8)\\])+/

Your use of + means match one-or-more so this means match [12345678] as many times as it occurs, and return that , which is why you get "[79bl9F5j][fKCebPYW][asd12233]" as your first result.

The .exec() method returns an array containing the whole match as result[0] followed by each capturing group in subsequent array elements. See the MDN doc for exec.

Your second array element is, therefore, the captured group , not repeated matches.

You want a global match because you want to find all occurrences of [12345678] so eliminate the + and add the g switch, which now gives a regex of /(\\[\\w{8)\\])/g

Let's assign that to a var so we don't have to keep retyping it:
> var re = /(\\[\\w{8)\\])/g;

.exec() gives you the first match when you run it:

> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[79bl9F5j]", "[79bl9F5j]"]

but with a global match you can run it again (and again)

> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[fKCebPYW]", "[fKCebPYW]"]

See this time it returns the second match. But it's returning each one twice... that's because of the capturing group. Let's drop that part and redefine our re then run the .exec...

> var re = /\[\w{8}\]/g;
undefined
> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[79bl9F5j]"]
> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[fKCebPYW]"]
> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[asd12233]"]

So, you can get all matches by running .exec() in a loop, re-using the regular expression on the same string, because the regexp object remembers the context.

But it's much easier than that — because instead of using RegExp.exec() you can String.match(regexp) which returns "An Array containing the entire match result..."

> var re = /\[\w{8}\]/g;
undefined
> "Text sample [79bl9F5j][fKCebPYW][asd12233]".match(re);
["[79bl9F5j]", "[fKCebPYW]", "[asd12233]"]
> "Text sample [79bl9F5j] x [fKCebPYW][asd12233]    [1234efgh]".match(re);
["[79bl9F5j]", "[fKCebPYW]", "[asd12233]", "[1234efgh]"]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM