【问题标题】:JavaScript equivalent of Ruby's String#scanJavaScript 等价于 Ruby 的 String#scan
【发布时间】:2012-12-03 10:33:30
【问题描述】:

这存在吗?

我需要解析如下字符串:

the dog from the tree

得到类似的东西

[[null, "the dog"], ["from", "the tree"]]

我可以在 Ruby 中使用一个 RegExp 和 String#scan

JavaScript 的 String#match 无法处理这个问题,因为它只返回匹配的正则表达式而不是捕获组,所以它返回类似

["the dog", "from the tree"]

因为我在我的 Ruby 应用程序中多次使用String#scan,所以如果有一种快速的方法可以在我的 JavaScript 端口中复制这种行为,那就太好了。

编辑:这是我正在使用的正则表达式:http://pastebin.com/bncXtgYA

【问题讨论】:

    标签: javascript ruby regex


    【解决方案1】:

    ruby 的 scan() 方法只有在指定捕获组时才会返回嵌套数组。 http://ruby-doc.org/core-2.5.1/String.html#method-i-scan

    a = "cruel world"
    a.scan(/\w+/)        #=> ["cruel", "world"]
    a.scan(/.../)        #=> ["cru", "el ", "wor"]
    a.scan(/(...)/)      #=> [["cru"], ["el "], ["wor"]]
    a.scan(/(..)(..)/)   #=> [["cr", "ue"], ["l ", "wo"]]
    

    以下是 melpomene 答案的修改版本,如果合适,可以返回平面数组。

    function scan(str, regexp) {
        if (!regexp.global) {
            throw new Error("RegExp without global (g) flag is not supported.");
        }
        var result = [];
        var m;
        while (m = regexp.exec(str)) {
            if (m.length >= 2) {
                result.push(m.slice(1));
            } else {
                result.push(m[0]);
            }
        }
        return result;
    }
    

    【讨论】:

      【解决方案2】:

      这是另一个使用String.replace的实现:

      String.prototype.scan = function(regex) {
          if (!regex.global) throw "regex must have 'global' flag set";
          var r = []
          this.replace(regex, function() {
              r.push(Array.prototype.slice.call(arguments, 1, -2));
          });
          return r;
      }
      

      工作原理:replace 将在每次匹配时调用回调,将匹配的子字符串、匹配的组、偏移量和完整字符串传递给它。我们只想要匹配的组,所以我们slice 排除其他参数。

      【讨论】:

      • 我之前看到过这个,但从来不明白如何实现这样的事情。我现在就试试。谢谢!
      • 顺便说一下,这是我正在使用的正则表达式。我做错了什么吗? pastebin.com/bncXtgYA
      • @itdoesntwork 它在 Chrome 中对我有用。您使用的是什么浏览器/浏览器版本?
      • Chrome,它可以工作。由于我直接从 Ruby 中复制了它,因此通常可能有问题。再次感谢!
      【解决方案3】:
      String.prototype.scan = function (re) {
          if (!re.global) throw "ducks";
          var s = this;
          var m, r = [];
          while (m = re.exec(s)) {
              m.shift();
              r.push(m);
          }
          return r;
      };
      

      【讨论】:

      • 我将此添加到我的代码中并直接将.match 替换为.scan,但它仍然不起作用。这是我正在使用的 RegExp:pastebin.com/bncXtgYA(测试字符串:"the dog in the tree")我直接从 Ruby 复制了 RegExp,而且我是 JS RegExp 的新手,所以它可能存在一些问题。
      • 不起作用”没有意义。我尝试了"the dog in the tree".scan(/(?:(in|into|to|at|from) )?((?:(?:the|a|an) )?(?:\d+\.|all\.)?(?:\w+|'[a-zA-Z0-9\s]*?'))/gi),得到了[[undefined, "the dog"], ["in", "the tree"]]
      • 啊,对不起,我是个笨蛋,我没有正确读取输出。谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 1970-01-01
      • 1970-01-01
      • 2011-08-18
      • 2019-03-14
      相关资源
      最近更新 更多