简体   繁体   中英

Repeating a capturing group

I have a String containing zero or more numbers, then zero or more characters ABCD . I want to parse the number into one group, then all characters into a separate group per character. I've tried:

([0-9]*)([ABCD])* : Captures number correctly, but only the last letter

([0-9]*)(([ABCD])*) : Captures number correctly, but then first all the letters in one group, then only the last letter in a group

I understand why each of those results happen, but I don't know how to fix it. How do I change my regex to give me multiple groups for the matched characters? Bonus points if I don't get an empty group ( '' or undefined ) if either the number or the letters aren't there.

For example:

1A => [1, A]

99 => [99]

CAB => [C, A, B]

1234ABCD => [1234, A, B, C, D]

JavaScript doesn't have a built in method for "match all." Since you know ahead of time that all of the letters will be the second match on, you can split these yourself:

var matches = "1234ABCD".match(/([0-9]*)([ABCD]*)/).slice(1);
matches = [matches[0]].concat(matches[1].split(""));

Allow me to propose a new strategy: instead of trying to match the whole string at one attempt, match every number or character once with the global modifier /g to return all matches.

Regex

/^\d+|[ABCD]/g
  • ^\\d+ matches an integer at the start of string
  • | ...or...
  • [ABCD] 1 of the four allowed characters.

Code

 subject = "1234ABCD"; pattern = /^\\d+|[ABCD]/g; matches = subject.match(pattern); console.log(matches); //=> ["1234", "A", "B", "C", "D"] 

Put asterisk inside of group capture. Asterisk means 0 or more, so you trying to capture 0 or more signs from group capture, is this case your result is just first captured letter. But you need 0 or more of ABCD letters.

([0-9]*)([ABCD]*)
([0-9]*)([A-D]*) //same thing

//UPDATE

var match = "".match(/([0-9]*)([ABCD]*)/)

This code will return you array with three positions:

  1. Mathed text
  2. First matched group -> All numbers
  3. Second matched group -> All letters

So to divide letters you can use

match[2].split('');

 var test = document.getElementById('test'); function reTest() { var re = /\\b([0-9]*)([ABCD]*)\\b/g; var str = test.value; var found = ""; str.replace(re, function(fullmatch, numbers, letters) { if (fullmatch == "") return; letters = letters.split(""); found += "<span class='num'>" + numbers + "</span>" found += "<span class='letters'>" + letters + "</span>\\n" }); document.getElementById('result').innerHTML = found; } reTest(); 
 span.num { color:red; } span.letters { color:blue; } 
 <textarea rows="7" cols="40" id='test'> 123ABC alpha 12345defg bravo CAB 19 9876vwxyz ...? </textarea><br/> <button onclick="reTest()">test</button><br/> <pre id='result'></pre> 

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