Ответ 1
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;
};
Это существует?
Мне нужно разобрать строку вроде:
the dog from the tree
и получить что-то вроде
[[null, "the dog"], ["from", "the tree"]]
который я могу сделать в Ruby с одним RegExp и String#scan
.
JavaScript String#match
не может справиться с этим, поскольку он просто возвращает то, что соответствует RegExp, а не группы захвата, поэтому он возвращает что-то вроде
["the dog", "from the tree"]
Поскольку я использовал String#scan
много раз в моем приложении Ruby, было бы неплохо, если бы был быстрый способ реплицировать это поведение в моем порт JavaScript.
EDIT: здесь используется RegExp: http://pastebin.com/bncXtgYA
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;
};
Здесь другая реализация с использованием 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
из других аргументов.