17

这存在吗?

我需要解析一个字符串,如:

the dog from the tree

并得到类似的东西

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

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

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

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

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

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

4

3 回答 3

14
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;
};
于 2012-12-15T19:32:37.430 回答
6

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;
}
于 2018-05-31T15:05:31.117 回答
5

这是另一个使用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排除了其他参数。

于 2012-12-15T20:22:37.133 回答