如何通过正则表达式在连续令牌之间抓取单词?



我正在尝试解析:hello::world:并分别抓取helloworld。不幸的是,以下结果如下:

const str = ':hello::world:'
const matches = str.match(/:[^s]+:/g)
console.log(matches) // [':hello::world:']

您的正则表达式匹配除导致匹配所有字符串的空格之外的任何字符串。所以你需要匹配除:以外的任何字符串

const str = ':hello::world:'
const matches = str.match(/[^:]+/g);
console.log(matches);

请注意,您可以在没有正则表达式的情况下完成这项工作。只需通过分隔符拆分字符串:并使用.filter()删除空项目

const str = ':hello::world:'
const matches = str.split(':').filter(v=>v!='');
console.log(matches)

您当前的正则表达式:[^s]+:匹配:,然后使用否定字符类来匹配非空格字符。这将匹配到示例字符串的末尾。

然后它将再次匹配一个:,这是字符串中的最后一:,导致:hello::world:

您可以做的是使用捕获组并在冒号之间匹配不([^:]+)冒号,并在结果中获取第一个捕获组。请注意,您不必转义冒号:

:([^:]+):

正则表达式演示

const regex = /:([^:]+):/g;
const str = `:hello::world:`;
let m;
while ((m = regex.exec(str)) !== null) {
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}
console.log(m[1]);
}

您的特定用例允许更简单的实现,但对您的问题非常严格,您可以使用以下正则表达式:

/(?<=:)([^:]+)(?=:)/g

它搜索冒号前后的任何非冒号文本。 这样,您可以将"str"更改为"start:hello::brave new world:end",它仍然符合您的规则,即"start"和"end"被排除在外,因为它们两侧都没有冒号,并且"美丽新世界"作为一个单元出现。

const str = 'start:hello::brave new world:end';
const matches = str.match(/(?<=:)([^:]+)(?=:)/g);
console.log(matches); // ["hello", "brave new world"]

正如@Mohammad指出的那样,回溯(括号中的第一部分)是一项新功能。 因此,您可以将我的方法调整为:

const str = 'start:hello::brave new world:end'
const matches = str.match(/:([^:]+)(?=:)/g).map(s => s.slice(1));
console.log(matches);

最新更新