真的很难为这个问题找到正确的措辞,我确信答案会在某处发布,而且与完全不了解RegExp.prototype.exec()的工作方式有关。
我有一个大型对象,其键是字符串并遵循此模式。 "foo.bar.baz": 'test'
其中每个段的长度都是任意长度,所有键都以foo开头,但其余部分各不相同。我需要构建一个包含所有中间段的数组,即。 '杆'在这个例子中。为此,我使用简单的正则表达式分组。
const myRegex = /foo\.([^\.]*)\./g
字符串以foo开头,然后是"。",然后捕获所有内容,直到下一个"。"。
使用上述键迭代对象,我想每次将中间部分(bar)附加到数组中,不包括重复项。
for(const key in myObject){ //loop over each key in the object
const matches = []
match = myRegex.exec(key)
if (match) {
if (matches.indexOf(match[1]) === -1) { //exclude duplicates
matches.push(match[1])
}
}
奇怪的行为是,这仅适用于具有多个匹配项的所有第二个段。例如,给出了下面的对象。
{
'foo.bar.bar': 'test',
'foo.bar.baz': 'test',
'foo.baz.bar': 'test',
'foo.baz.baz': 'test',
'foo.bam.bar': 'test'
}
只有bar,baz才会被推到比赛中。如果将foo.bam.baz: 'test'
添加到对象,则匹配bam并将其推送到数组。如果删除foo.bar.x
或foo.baz.x
中的一个,则不会推送该密钥。它似乎只是在第二次尝试时匹配,我无法弄清楚原因。
非常感谢任何见解。
答案 0 :(得分:1)
看起来正则表达式对象是有状态的:
var myRegex = /foo\.([^\.]*)\./g;
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
console.log(myRegex.exec("foo.bar.bar"))
(2) ["foo.bar.", "bar", index: 0, input: "foo.bar.bar"]
null
(2) ["foo.bar.", "bar", index: 0, input: "foo.bar.bar"]
null
(2) ["foo.bar.", "bar", index: 0, input: "foo.bar.bar"]
null
(2) ["foo.bar.", "bar", index: 0, input: "foo.bar.bar"]
null
(2) ["foo.bar.", "bar", index: 0, input: "foo.bar.bar"]
答案 1 :(得分:0)
您可以使用Object.keys()
获取对象的属性值,.map()
来迭代属性,RegExp
/^foo\.|\.\w+$/g
以匹配"foo"
和"."
后跟一个或多个单词字符,后跟字符串结尾Set
,以从结果集合中删除重复项,然后将Set
转换为数组
const o = {
'foo.bar.bar': 'test',
'foo.bar.baz': 'test',
'foo.baz.bar': 'test',
'foo.baz.baz': 'test',
'foo.bam.bar': 'test'
}
let matches = [...new Set(Object.keys(o).map(prop =>
prop.replace(/^foo\.|\.\w+$/g, "")))];
console.log(matches);