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

时间:2018-12-14 14:55:07

标签: javascript regex

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

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

3 个答案:

答案 0 :(得分:4)

您的正则表达式与任何字符串匹配,但空格导致所有字符串匹配。因此,您需要匹配:

以外的任何字符串

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) 

答案 1 :(得分: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);

答案 2 :(得分:1)

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

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

您可以做的是使用捕获组,而不在冒号之间匹配冒号([^:]+),结果得到第一个捕获组。请注意,您不必逃脱冒号:

:([^:]+):

Regex demo

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]);
}