【问题标题】:Match string in between two strings [duplicate]在两个字符串之间匹配字符串[重复]
【发布时间】:2016-02-26 05:42:27
【问题描述】:

如果我有这样的字符串:

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”之间的字符串,所以我得到“黎巴嫩的 Ukulele。弹吉他”而不是 2 个单独的字符串。有谁知道如何全局搜索字符串以查找起始字符串和结束字符串之间所有出现的子字符串?

【问题讨论】:

  • str.match("play(.*)in") ==> str.match(/play(.*?)in/g)

标签: javascript regex string string-matching


【解决方案1】:

你可以使用正则表达式

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>';

【讨论】:

  • 我在您的表达中发现了一些可能的问题。我在回答中引用了它。
  • 感谢这是完美的 ;)
【解决方案2】:

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

我相信之前提供的正则表达式可能存在一些问题。例如,/play\s*(.*?)\s*in/g 将在“显示播放照片in序列”中找到匹配项。当然这不是你想要的。问题之一是没有规定“游戏”应该是一个离散的词。它前面需要一个单词边界,后面至少需要一个空白实例(它不能是可选的)。同样,捕获组后面的空格也不应该是可选的。

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

至于您的表达,它也缺少单词边界和空白标记。但正如另一个提到的,它还需要通配符是惰性的。否则,给定您的示例字符串,您的匹配将从“play”的第一个实例开始,以“in”的第二个实例结束。

如果发现我提供的表达方式存在问题,请提供反馈。

【讨论】:

    【解决方案3】:

    您离正确答案如此接近。您可能会忽略以下几点:

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

    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 );
    &lt;pre id="demo"&gt;&lt;/pre&gt;

    【讨论】:

    • 谢谢先生,这是一个很好的答案。另一个用户给了我/play\s*(.*?)\s*in/g 的正则表达式,但你的看起来要简单得多。语法看起来很乱,所以我还在努力理解它。
    • 我忙着打字,没有注意到@Tushar 得到了几乎相同的答案,除了对数组的赋值。在 JavaScript 中,你可以使用`, \s, or \`来引用一个空格。在其他地方要小心,比如 Perl,其中 ` 可以被忽略。此外,\s 不仅仅指空格,它还可能意味着制表符或换行符。
    • @vol7ron:我在你的表达中发现了一些可能的问题。我在回答中引用了它。
    • @Jon 谢谢,你是对的,这可以使用单词边界。请记住,即使是单词边界也可能存在连字符问题。最强大的解决方案将需要更多的逻辑行 - 或负面的后视(我不认为 ECMAScript RegEx 允许)。因此,这也要求 OP 更具体地了解正在评估的字符串。也就是说,\b 将是一件好事。
    • @vol7ron:是的,\b 可能会遇到许多特殊字符的问题。可能我做的比需要的更多,因为 OP 正在处理的字符串可能与他上面提供的字符串几乎没有什么不同,在这种情况下 \b 将是不必要的。此外,他的问题可能真的只是关于贪婪与懒惰。但我想,虽然\b 的潜在问题问题已经提出(正如你所暗示的那样,在不了解他的输入字符串可能存在的变化的情况下),也许以下内容会更安全:/(?:\s|^)play\s+(.+?)\s+in\s/ig
    【解决方案4】:

    贪婪匹配的受害者。

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

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

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

        the Ukelele
        the Guitar
        Lebanon
    

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 1970-01-01
      • 2014-11-15
      相关资源
      最近更新 更多