最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

regex - Javascript .match regular expression with reverse quantifier (or parse right to left) - Stack Overflow

programmeradmin0浏览0评论

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?

Share Improve this question edited Dec 5, 2017 at 7:56 cнŝdk 32.1k7 gold badges60 silver badges80 bronze badges asked Dec 4, 2017 at 19:46 Robert WadeRobert Wade 5,0031 gold badge18 silver badges37 bronze badges 4
  • This .{3}|.{2}|. or ...|..|.? Otherwise what @WiktorStribiżew says below – ctwheels Commented Dec 4, 2017 at 19:47
  • 4 You can reverse() a string and run your regex on it, then reverse() 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
  • Thank you @WiktorStribiżew That's what I was starting to figure out. Was mostly wondering if there's a way to modify the pattern to parse right to left without running reverse() or other operations. – Robert Wade Commented Dec 4, 2017 at 19:52
  • @RobertWade not in JavaScript. Other languages like C# provide a flag that allows you to run regex rtl instead of ltr, but that's not available in many languages. – ctwheels Commented Dec 4, 2017 at 19:54
Add a comment  | 

3 Answers 3

Reset to default 17

Regular 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 original string.
  • Then call .match() with this reversed string.
  • 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)))));
发布评论

评论列表(0)

  1. 暂无评论