Given a string like such...
"ABCDEFG"
Is it possible to have a quantifier that works in "reverse" so to say?
For instance:
var foo = "ABCDEFG";
foo.match(/.{1,3}/g);
Results in:
// Array(3) ["ABC", "DEF", "G"]
What I'm trying achieve:
// Array(3) ["A", "BCD", "EFG"]
So regardless of the string length, the array is always a representation of the string, with each node 3 characters in length (except possibly the 1st) but always starting at the end of the string. So the first array item might be 1, 2 or 3 characters long, simply depending on what's "left over".
I have tried using the following to error:
foo.match(/.{-1,3}/g); // null
foo.match(/.{1,-3}/g); // null
Thinking perhaps I could use negatives similar to splitting strings, however each of those examples returns null.
I'm assuming this can be done within the pattern somehow and not the quantifier, so I'd like to understand how that would be written with .match()
. Or would this require having to write a custom method that would involve other string manipulation in order to accomplish this?
Given a string like such...
"ABCDEFG"
Is it possible to have a quantifier that works in "reverse" so to say?
For instance:
var foo = "ABCDEFG";
foo.match(/.{1,3}/g);
Results in:
// Array(3) ["ABC", "DEF", "G"]
What I'm trying achieve:
// Array(3) ["A", "BCD", "EFG"]
So regardless of the string length, the array is always a representation of the string, with each node 3 characters in length (except possibly the 1st) but always starting at the end of the string. So the first array item might be 1, 2 or 3 characters long, simply depending on what's "left over".
I have tried using the following to error:
foo.match(/.{-1,3}/g); // null
foo.match(/.{1,-3}/g); // null
Thinking perhaps I could use negatives similar to splitting strings, however each of those examples returns null.
I'm assuming this can be done within the pattern somehow and not the quantifier, so I'd like to understand how that would be written with .match()
. Or would this require having to write a custom method that would involve other string manipulation in order to accomplish this?
3 Answers
Reset to default 17Regular expressions always match from left to right, but you can use a positive lookahead with an end-of-string anchor to achieve what you want:
var foo = "ABCDEFG";
foo.match(/.{1,3}(?=(.{3})*$)/g); // ["A", "BCD", "EFG"]
Here the subpattern (?=(.{3})*$)
is a lookahead expression that matches zero or more repetitions of (exactly!) 3 characters, bounded at the end of the string ($
).
As stated in comments there's no regex or quantifier that matches your string from backwards reading from right to left.
What you can do here is to reverse the string
before calling .match()
then reverse the matches array
:
var matches = foo.split("").reverse().join("")
.match(/.{1,3}/g).map(m => m.split("").reverse().join(""))
.reverse();
Explanation:
- We use
foo.split("").reverse().join("")
to reverse the originalstring
. - Then call
.match()
with this reversedstring
. - Reverese the matches with
.map(m => m.split("").reverse().join(""))
. - And finally reverse the matches
array
.
Demo:
var foo = "ABCDEFG";
var matches = foo.split("").reverse().join("").match(/.{1,3}/g).map(m => m.split("").reverse().join("")).reverse();
console.log(matches);
If you construct a custom regex, you can use that to pull out the matches in the right order:
var foo = "ABCDEFG";
console.log(foo.match(new RegExp("(.{"+foo.length % 3+"})"+"(...)".repeat(Math.floor(foo.length / 3)))));
.{3}|.{2}|.
or...|..|.
? Otherwise what @WiktorStribiżew says below – ctwheels Commented Dec 4, 2017 at 19:47reverse()
a string and run your regex on it, thenreverse()
the results. No quantifier will be able to do what you ask for since the string is parsed from left to right. – Wiktor Stribiżew Commented Dec 4, 2017 at 19:47