【问题标题】:Regex to extract substring, returning 2 results for some reason正则表达式提取子字符串,由于某种原因返回 2 个结果
【发布时间】:2022-12-17 20:47:06
【问题描述】:

我需要在 javascript 中做很多正则表达式的事情,但是语法有一些问题,我似乎无法找到关于这个的权威资源.. 出于某种原因,当我这样做时:

var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test)

表明

"afskfsd33j, fskfsd33"

我不确定为什么它会给出原始字符串和匹配字符串的输出,我想知道如何让它只给出匹配项(本质上是从原始字符串中提取我想要的部分)

感谢您的任何建议

【问题讨论】:

  • 请注意,您没有声明的原始字符串和匹配的字符串。您有匹配的字符串“afskfsd33j”。然后第二项“fskfsd33”来自您的正则表达式中的括号:(.*)

标签: javascript regex substring


【解决方案1】:

match 返回一个数组。

JavaScript 中数组的默认字符串表示形式是用逗号分隔的数组元素。在这种情况下,所需的结果位于数组的第二个元素中:

var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test[1]);

【讨论】:

  • 哦,好吧,我想我错过了..谢谢,我有时会对 javascript 感到困惑,因为我习惯了在 php 中打印数组的更受限制的方式
  • 我可能听起来很蠢,但为什么 match 会返回原始字符串?有这方面的文件吗?
  • @john-lee 这是因为原始字符串匹配正则表达式/a(.*)j/,而数组的第二个条目包含第一个匹配组(.*)。此外,group(0) 始终是整个匹配项,而 group(n) 是用方括号标记的第 n 个组。如果不尝试this documentation for more information.,我希望这是可以理解的
【解决方案2】:

括号 () 定义的每个组在处理过程中被捕获,每个捕获的组内容被推入结果数组,顺序与模式开始中的组相同。在 http://www.regular-expressions.info/brackets.htmlhttp://www.regular-expressions.info/refcapture.html 上查看更多信息(选择正确的语言以查看支持的功能)

var source = "afskfsd33j"
var result = source.match(/a(.*)j/);

result: ["afskfsd33j", "fskfsd33"]

您收到此确切结果的原因如下:

数组中的第一个值是第一个找到的字符串,它确认了整个模式。所以它绝对应该以“a”开头,后跟任意数量的任何字符,并在开始“a”之后以第一个“j”字符结束。

数组中的第二个值是由括号定义的捕获组。在您的案例中,组包含整个模式匹配,没有在括号外定义的内容,所以正是“fskfsd33”。

如果你想去掉数组中的第二个值,你可以这样定义模式:

/a(?:.*)j/

其中“?:”表示匹配括号中内容的字符组不会成为结果数组的一部分。

在这种简单的情况下,其他选项可能是在没有任何组的情况下编写模式,因为根本不需要使用组:

/a.*j/

如果您只想检查源文本是否与模式匹配并且不关心找到的文本比您可以尝试:

var result = /a.*j/.test(source);

结果应该只返回 true|false 值。有关详细信息,请参阅http://www.javascriptkit.com/javatutors/re3.shtml

【讨论】:

    【解决方案3】:

    我认为你的问题是 match 方法返回一个数组。数组中的第 0 项是原始字符串,第 1 到第 n 项对应于第 1 到第 n 匹配的括号中的项。您的“alert()”调用显示了整个数组。

    【讨论】:

    • 我不知道这是不正确的还是措辞不当。数组中的第一个元素 (test[0]) 不是整个字符串,它是整个正则表达式匹配的字符串部分。在这种情况下,它们碰巧是相同的,但如果正则表达式是 /f(.*)j/,则结果将是 fskfsd33j, skfsd33(匹配中不包括初始的 a)。
    【解决方案4】:

    只需去掉括号,这将为您提供一个包含一个元素的数组,并且:

    • 改变这一行

      var test = tesst.match(/a(.*)j/);

    • 对此

      var test = tesst.match(/a.*j/);

    如果添加括号,match() 函数将为您找到两个匹配项,一个匹配整个表达式,另一个匹配括号内的表达式

    • 同样根据 developer.mozilla.org 文档:

    如果您只想找到第一个匹配项,则可能需要使用 RegExp.exec() 代替。

    您可以使用以下代码:

    RegExp(/a.*j/).exec("afskfsd33j")
    

    【讨论】:

      【解决方案5】:

      我刚刚遇到了同样的问题。

      如果包含匹配组(在括号中)和“g”(全局)修饰符,您只会在结果中获得两次文本。 第一项始终是第一个结果,通常在短字符串上使用 match(reg) 时可以,但是当使用如下结构时:

      while ((result = reg.exec(string)) !== null){
          console.log(result);
      }
      

      结果有点不同。

      试试下面的代码:

      var regEx = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
      var result = sample_string.match(regEx);
      console.log(JSON.stringify(result));
      // ["1 cat","2 fish"]
      
      var reg = new RegExp('[0-9]+ (cat|fish)','g'), sampleString="1 cat and 2 fish";
      while ((result = reg.exec(sampleString)) !== null) {
          console.dir(JSON.stringify(result))
      };
      // '["1 cat","cat"]'
      // '["2 fish","fish"]'
      
      var reg = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
      while ((result = reg.exec(sampleString)) !== null){
          console.dir(JSON.stringify(result))
      };
      // '["1 cat","1 cat","cat"]'
      // '["2 fish","2 fish","fish"]'
      

      (在最近的 V8 - Chrome、Node.js 上测试过)

      最佳答案目前是我无法投票的评论,所以归功于@Mic。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-05
        • 1970-01-01
        • 2020-03-26
        • 1970-01-01
        • 1970-01-01
        • 2021-01-23
        相关资源
        最近更新 更多