Reputation:
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]
Upvotes: 3
Views: 674
Reputation: 6511
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"]
Upvotes: 1
Reputation: 2661
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>
Upvotes: 0
Reputation: 193
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 A B C D 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:
So to divide letters you can use
match[2].split('');
Upvotes: 0
Reputation: 191729
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(""));
Upvotes: 2