匹配两个字符串之间的字符串

Match string in between two strings

如果我有这样的字符串:

var str = "play the Ukulele in Lebanon. play the Guitar in Lebanon.";

我想获取每个子字符串 "play" 和 "in" 之间的字符串,所以基本上是一个包含 "the Ukelele" 和 "the Guitar" 的数组。

现在我在做:

var test = str.match("play(.*)in");

但是这是返回第一个 "play" 和最后一个 "in" 之间的字符串,所以我得到 "the Ukulele in Lebanon. Play the Guitar" 而不是 2 个单独的字符串。有谁知道如何全局搜索字符串以查找开始和结束字符串之间出现的所有子字符串?

您可以使用正则表达式

play\s*(.*?)\s*in

  1. 使用 / 作为正则表达式语法的分隔符
  2. 使用惰性组匹配最小可能

演示:

var str = "play the Ukulele in Lebanon. play the Guitar in Lebanon.";
var regex = /play\s*(.*?)\s*in/g;

var matches = [];
while (m = regex.exec(str)) {
  matches.push(m[1]);
}

document.body.innerHTML = '<pre>' + JSON.stringify(matches, 0, 4) + '</pre>';

贪婪匹配的受害者。

.* 找到可能的最长匹配,

而.*?找到可能的最短匹配项。

对于给定的示例 str 将是一个数组或 3 个字符串,其中包含:

    the Ukelele
    the Guitar
    Lebanon

你离正确答案太近了。您可能会忽略一些事情:

  1. 您需要您的匹配是非贪婪的,这可以通过使用 ? 运算符
  2. 来实现
  3. 不要使用 String.match() 方法,因为它已被证明可以匹配整个模式,并且不会像您期望的那样注意捕获组。另一种方法是使用 RegExp.exec()String.replace(),但使用 replace 需要更多的工作,因此请坚持使用 exec[=28= 构建您自己的数组]

var str     = "display the Ukulele in Lebanon. play the Guitar in Lebanon.";
var re      = /\bplay (.+?) in\b/g;
var matches = [];
var match;

while ( match = re.exec(str) ){
  matches[ matches.length ] = match[1];
}


document.getElementById('demo').innerHTML = JSON.stringify( matches );
<pre id="demo"></pre>

/\bplay\s+(.+?)\s+in\b/ig 可能更具体并且可能更适合您。

我认为之前提供的正则表达式可能存在一些问题。例如,/play\s*(.*?)\s*in/g 将在 "displaying photographs in sequence" 中找到匹配项。当然这不是你想要的。问题之一是没有任何内容指定 "play" 应该是一个离散词。它前面需要一个单词边界,后面至少有一个 white space 实例(它不能是可选的)。同样,捕获组后面的白色space也不应该是可选的。

我添加时提供的另一个表达式 /play (.+?) in/g 在 "play" 之前和 "in" 之后缺少单词边界标记,因此它将包含 [=] 中的匹配项35=]。这不是你想要的。

至于你的表达,它缺少单词边界和白色 space 标记。但是正如另一个提到的那样,它还需要通配符才能变得懒惰。否则,给定您的示例字符串,您的匹配项将从 "play" 的第一个实例开始,并以 "in".

的第二个实例结束

如果发现我提供的表达式有问题,将不胜感激反馈。