【问题标题】:Regex to find pattern matching two strings with 'x' number of spaces between them正则表达式查找匹配两个字符串的模式,它们之间有“x”个空格
【发布时间】:2017-07-20 22:41:14
【问题描述】:

我有一种情况,我正在寻找一个接一个的特定单词,但我不知道这些单词之间有多少空格,现在我想到了那里还有括号。

这是一个例子:

word1 word2('word3')

我正在寻找的正则表达式必须找到可以有任意数量空格的模式:

  • word1 和 word2 之间

  • word2 和 (

  • 之间
  • 介于 ( 和 '

  • 在'和)之间

我只想要 word3,而不是 'word3'。

有人知道正则表达式的外观吗?我被难住了。

我不知道 word3 是什么,但我知道 word1 和 word2 是什么。

另一个例子:

字符串中可以多次出现这种模式。

说我的文字如下:

car   audi('q5') blah blah blah car    audi  ( 'a3') blah blah
more blah and even more car  audi( 'r8' ) blah end.

我想要的只是:q5、a3、r8

就是这样。我不知道这些值是什么或有多少,我只知道“汽车”和“奥迪”。

【问题讨论】:

  • 在模式中随处放置带量词的空格,并使用捕获组来获取“word3”。
  • 您目前使用的是什么正则表达式?请包括您的尝试
  • 可能没有理由担心单词之间的内容。只需使用\b 搜索单词边框。例如:\b\w+\b
  • 你的问题有点含糊。即使使用 Edit 2,它仍然不清楚您的要求。我试图理解这一切,而且,它的措辞方式就是为什么你最终会得到非常不同的答案。考虑重写你的问题,让我清楚你的要求。

标签: javascript node.js regex


【解决方案1】:

这个怎么样:

/word1\s*word2\s*\(\s*'word3'\s*\)/g

看到这个工作Regexr

let strings = [
  "word1 word2('word3')",
  "word1   word2('word3')",
  "word1 word2  ('word3')",
  "word1 word2(    'word3')",
  "word1 word2('word3'     )",
  "word1    word2    (   'word3'   )",
  "word1word2('word3')",
];

for (const str of strings) {
  console.log(`"${str}" -> ${/word1\s*word2\s*\(\s*'word3'\s*\)/g.test(str)}`);
}

结果:

"word1 word2('word3')" -> true
"word1   word2('word3')" -> true
"word1 word2  ('word3')" -> true
"word1 word2(    'word3')" -> true
"word1 word2('word3'     )" -> true
"word1    word2    (   'word3'   )" -> true
"word1word2('word3')" -> true

【讨论】:

    【解决方案2】:

    var strr  = "word1 word2('word3')somethingDifferent";
    console.log( strr.replace(/(\(|\)|')/g,' ').replace(/\s+/g , ' '));

    【讨论】:

      【解决方案3】:

      我们需要两个正则表达式:

      1. 第一个正则表达式将用于提取字符串,例如:car audi ('q5')
      2. 第二个正则表达式将用于清理匹配的字符串以获得:q5

      var str = [
        "car   audi('q5') blah blah blah car    audi  ( 'a3') blah blah",
        "more blah and even more car  audi( 'r8' ) blah end."
      ].join("\n") + "\n";
      
      var m = str.match(/(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/g);
      
      console.log("Intermediate results:");
      console.log(m);
      
      // m = [
      //  "car   audi('q5')",
      //  "car    audi  ( 'a3')",
      //  "car  audi( 'r8' )"
      // ]
      
      m = m.map(function (e) {
        return e.match(/(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/)[3];
      } );
      
      console.log("Final results:");
      console.log(m);
      
      // m = [ 'q5', 'a3', 'r8' ]

      让我们了解为什么会这样。 我使用的第一个正则表达式如下所示:

      /(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/g
      

      即使我使用了捕获组,它们也会被忽略,因为我在末尾添加了 /g。这将匹配与您所需模式匹配的所有句子。它会准确找到这 3 个汽车 audi 语句。

      然后,我使用的第二个正则表达式如下所示:

      /(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/
      

      即我删除了/g。现在每个单词的捕获组将分别匹配 car audiq5。您表示您对第 3 个单词感兴趣,这就是为什么我将 [3] 放在末尾以仅获取第 3 个单词并丢弃匹配中的其他所有内容。

      下面是正则表达式中关键组件的解释:

      • \w+ 将匹配包含 1 个或多个字母或数字的单词
      • \s* 将匹配 0、1 或更多空格。
      • (\w+) 不仅会匹配单词,还会将其放入捕获组(即给我一份副本)

      这是解决方案的简化版本:

      var str = [
          "car   audi('q5') blah blah blah car    audi  ( 'a3') blah blah",
          "more blah and even more car  audi( 'r8' ) blah end."
      ].join("\n") + "\n";
      
      var m = (str.match(/(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/g) || []).map(function (e) {
        return e.match(/(car)\s*(audi)\s*\(\s*'(\w+)'\s*\)/)[3];
      } );
      
      console.log(m); // ["q5","a3","r8"]

      还要注意,在这个最终版本中,我添加了|| []。这是为了处理没有匹配句子的情况,以确保我们返回一个干净的空数组,而不是由于空中间结果而导致错误。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-09-26
        • 2018-07-16
        • 1970-01-01
        • 1970-01-01
        • 2011-08-31
        • 1970-01-01
        相关资源
        最近更新 更多