Javascript .match 带反向量词的正则表达式(或从右到左解析)
Javascript .match regular expression with reverse quantifier (or parse right to left)
给出这样的字符串...
"ABCDEFG"
可以这么说 "reverse" 有一个量词吗?
例如:
var foo = "ABCDEFG";
foo.match(/.{1,3}/g);
结果:
// Array(3) ["ABC", "DEF", "G"]
我正在努力实现的目标:
// Array(3) ["A", "BCD", "EFG"]
因此,无论字符串长度如何,数组始终是字符串的表示,每个节点的长度为 3 个字符(可能第 1 个字符除外),但始终从字符串的末尾开始。所以第一个数组项可能是 1、2 或 3 个字符长,这取决于什么是 "left over".
我试过使用下面的错误:
foo.match(/.{-1,3}/g); // null
foo.match(/.{1,-3}/g); // null
我想也许我可以使用类似于拆分字符串的否定,但是每个示例 returns null。
我假设这可以在模式中以某种方式完成,而不是量词,所以我想了解如何用 .match()
编写它。或者这是否需要编写一个涉及其他字符串操作的自定义方法才能完成此操作?
如果您构建自定义正则表达式,则可以使用它以正确的顺序提取匹配项:
var foo = "ABCDEFG";
console.log(foo.match(new RegExp("(.{"+foo.length % 3+"})"+"(...)".repeat(Math.floor(foo.length / 3)))));
如评论中所述,没有正则表达式或量词与从右到左向后读取的字符串相匹配。
你在这里可以做的是在调用 .match()
之前反转 string
然后反转匹配 array
:
var matches = foo.split("").reverse().join("")
.match(/.{1,3}/g).map(m => m.split("").reverse().join(""))
.reverse();
解释:
- 我们用
foo.split("").reverse().join("")
反转原来的string
.
- 然后调用
.match()
并反转 string
。
- 用
.map(m => m.split("").reverse().join(""))
反转比赛。
- 最后逆转比赛
array
。
演示:
var foo = "ABCDEFG";
var matches = foo.split("").reverse().join("").match(/.{1,3}/g).map(m => m.split("").reverse().join("")).reverse();
console.log(matches);
正则表达式始终从左到右匹配,但您可以使用带有字符串结尾锚点的正向先行来实现您想要的结果:
var foo = "ABCDEFG";
foo.match(/.{1,3}(?=(.{3})*$)/g); // ["A", "BCD", "EFG"]
这里的子模式 (?=(.{3})*$)
是一个前瞻表达式,它匹配零个或多个重复的(准确地说!)3 个字符,在字符串的末尾限定 ($
)。
给出这样的字符串...
"ABCDEFG"
可以这么说 "reverse" 有一个量词吗?
例如:
var foo = "ABCDEFG";
foo.match(/.{1,3}/g);
结果:
// Array(3) ["ABC", "DEF", "G"]
我正在努力实现的目标:
// Array(3) ["A", "BCD", "EFG"]
因此,无论字符串长度如何,数组始终是字符串的表示,每个节点的长度为 3 个字符(可能第 1 个字符除外),但始终从字符串的末尾开始。所以第一个数组项可能是 1、2 或 3 个字符长,这取决于什么是 "left over".
我试过使用下面的错误:
foo.match(/.{-1,3}/g); // null
foo.match(/.{1,-3}/g); // null
我想也许我可以使用类似于拆分字符串的否定,但是每个示例 returns null。
我假设这可以在模式中以某种方式完成,而不是量词,所以我想了解如何用 .match()
编写它。或者这是否需要编写一个涉及其他字符串操作的自定义方法才能完成此操作?
如果您构建自定义正则表达式,则可以使用它以正确的顺序提取匹配项:
var foo = "ABCDEFG";
console.log(foo.match(new RegExp("(.{"+foo.length % 3+"})"+"(...)".repeat(Math.floor(foo.length / 3)))));
如评论中所述,没有正则表达式或量词与从右到左向后读取的字符串相匹配。
你在这里可以做的是在调用 .match()
之前反转 string
然后反转匹配 array
:
var matches = foo.split("").reverse().join("")
.match(/.{1,3}/g).map(m => m.split("").reverse().join(""))
.reverse();
解释:
- 我们用
foo.split("").reverse().join("")
反转原来的string
. - 然后调用
.match()
并反转string
。 - 用
.map(m => m.split("").reverse().join(""))
反转比赛。 - 最后逆转比赛
array
。
演示:
var foo = "ABCDEFG";
var matches = foo.split("").reverse().join("").match(/.{1,3}/g).map(m => m.split("").reverse().join("")).reverse();
console.log(matches);
正则表达式始终从左到右匹配,但您可以使用带有字符串结尾锚点的正向先行来实现您想要的结果:
var foo = "ABCDEFG";
foo.match(/.{1,3}(?=(.{3})*$)/g); // ["A", "BCD", "EFG"]
这里的子模式 (?=(.{3})*$)
是一个前瞻表达式,它匹配零个或多个重复的(准确地说!)3 个字符,在字符串的末尾限定 ($
)。