有人能解释一下数组的regex过滤吗

时间:2022-09-07 11:08:36

I'm filtering an array, and found a regex on here. I'm trying to understand this:

我过滤了一个数组,在这里找到了一个regex。我试着理解这个:

filterArray.filter(/./.test.bind(new RegExp(key, 'g')))

But I don't understand how the array tests it value against the regex or why you have to start with /./ instead of just writing the regex. And how does bind work in this case?

但是我不理解数组如何针对regex测试它的值,也不理解为什么必须从/开始。/而不仅仅是写regex。在这种情况下,绑定是如何工作的呢?

EDIT: Key is just a string that I want to match, "hi" or "dog" or "anything really".

编辑:Key只是我想匹配的字符串,“hi”、“dog”或“anything really”。

2 个解决方案

#1


14  

The .bind() method will return a function with whatever you passed as the first argument bound as the value of this.

bind()方法将返回一个函数,该函数具有作为第一个参数绑定的值。

Since you're calling .bind() from .test(), you're getting the .test() method with the this bound to new RegExp(key, 'g').

由于您正在从.test()调用.bind(),所以您将获得.test()方法,并将其绑定到新的RegExp(key, 'g')。

The /./ is irrelevant here. It's just short way of getting to the RegExp.prototype.test method.

/。/这里是无关紧要的。这只是到regexpe .prototype的一小段路。测试方法。

The result is that you'll effectively be doing:

结果是你将有效地做:

var regexp = new RegExp(key, 'g');

filterArray.filter(function(val) {
    return regexp.test(val);
});

You should note that this is a little bit dangerous, because a regex object with the g modifier is stateful. This means it always starts a new search where the previous one left off.

您应该注意,这有点危险,因为带有g修饰符的regex对象是有状态的。这意味着它总是在前一个搜索结束的地方开始新的搜索。

Given this filtering scenario, the g doesn't seem at all necessary, and could really only cause problems.

考虑到这种过滤场景,g似乎根本没有必要,而且可能只会导致问题。

Here's an example of the danger of using the g here:

这里有一个使用g的危险的例子:

var re = /./.test.bind(new RegExp("foo", 'g'));
var str = "foobar";

console.log(re(str));  // true
console.log(re(str));  // false

So calling the same regex on the same string produces two different results. If we called it again, it would be true once again.

因此,在同一个字符串上调用相同的regex将产生两个不同的结果。如果我们再次调用它,它将再次为真。


So given the use as a .filter() callback, let's say key is "foo", then lets say one val is "foobar". It will be allowed through the filter.

因此,考虑到它作为.filter()回调的使用,我们假设key是“foo”,然后假设一个val是“foobar”。它将被允许通过过滤器。

But let's say the very next val is "foobaz". The search will resume on the fourth character instead of starting from the first, so the "foo" will not be found.

但让我们假设下一个瓦尔是“foobaz”。搜索将在第四个字符上继续,而不是从第一个字符开始,因此不会找到“foo”。


Here's concrete example that shows the issue in action:

下面是一个具体的例子,说明了这个问题的实际作用:

DEMO: http://jsfiddle.net/s9PzL/

演示:http://jsfiddle.net/s9PzL/

var filterArray = [
    "foobar",
    "foobaz",
    "foobuz",
    "foobix"
];

var result = filterArray.filter(/./.test.bind(new RegExp("foo", 'g')));

All the strings have "foo", so they should all get through. But the result shows that doesn't happen.

所有的弦都有foo,所以它们都应该通过。但结果表明这并没有发生。

document.body.textContent = result.join(", "); // foobar, foobuz

#2


6  

I think the reason this is done this way is because you want to execute the test method on each item in the array. Just passing the test method to filter will (presumably) mess up the binding of the method.

我认为这样做的原因是您希望对数组中的每个项执行测试方法。仅仅将测试方法传递给筛选器将(可能)打乱方法的绑定。

That's why in your example:

这就是为什么在你的例子中:

/./

Generates an empty regex

生成一个空的正则表达式

/./.test

is the test method on that regex

那个regex上的测试方法是什么

/./.test.bind(new Regex(..))

binds that method to the requested method, and returns a new method that executes test where this is your supplied regex based on key.

将该方法绑定到所请求的方法,并返回一个新的方法,该方法执行基于key的测试。

It seems that it could have been written a lot more clear:

似乎可以写得更清楚些:

RegExp.prototype.test.bind(new RegExp(key, 'g'))

#1


14  

The .bind() method will return a function with whatever you passed as the first argument bound as the value of this.

bind()方法将返回一个函数,该函数具有作为第一个参数绑定的值。

Since you're calling .bind() from .test(), you're getting the .test() method with the this bound to new RegExp(key, 'g').

由于您正在从.test()调用.bind(),所以您将获得.test()方法,并将其绑定到新的RegExp(key, 'g')。

The /./ is irrelevant here. It's just short way of getting to the RegExp.prototype.test method.

/。/这里是无关紧要的。这只是到regexpe .prototype的一小段路。测试方法。

The result is that you'll effectively be doing:

结果是你将有效地做:

var regexp = new RegExp(key, 'g');

filterArray.filter(function(val) {
    return regexp.test(val);
});

You should note that this is a little bit dangerous, because a regex object with the g modifier is stateful. This means it always starts a new search where the previous one left off.

您应该注意,这有点危险,因为带有g修饰符的regex对象是有状态的。这意味着它总是在前一个搜索结束的地方开始新的搜索。

Given this filtering scenario, the g doesn't seem at all necessary, and could really only cause problems.

考虑到这种过滤场景,g似乎根本没有必要,而且可能只会导致问题。

Here's an example of the danger of using the g here:

这里有一个使用g的危险的例子:

var re = /./.test.bind(new RegExp("foo", 'g'));
var str = "foobar";

console.log(re(str));  // true
console.log(re(str));  // false

So calling the same regex on the same string produces two different results. If we called it again, it would be true once again.

因此,在同一个字符串上调用相同的regex将产生两个不同的结果。如果我们再次调用它,它将再次为真。


So given the use as a .filter() callback, let's say key is "foo", then lets say one val is "foobar". It will be allowed through the filter.

因此,考虑到它作为.filter()回调的使用,我们假设key是“foo”,然后假设一个val是“foobar”。它将被允许通过过滤器。

But let's say the very next val is "foobaz". The search will resume on the fourth character instead of starting from the first, so the "foo" will not be found.

但让我们假设下一个瓦尔是“foobaz”。搜索将在第四个字符上继续,而不是从第一个字符开始,因此不会找到“foo”。


Here's concrete example that shows the issue in action:

下面是一个具体的例子,说明了这个问题的实际作用:

DEMO: http://jsfiddle.net/s9PzL/

演示:http://jsfiddle.net/s9PzL/

var filterArray = [
    "foobar",
    "foobaz",
    "foobuz",
    "foobix"
];

var result = filterArray.filter(/./.test.bind(new RegExp("foo", 'g')));

All the strings have "foo", so they should all get through. But the result shows that doesn't happen.

所有的弦都有foo,所以它们都应该通过。但结果表明这并没有发生。

document.body.textContent = result.join(", "); // foobar, foobuz

#2


6  

I think the reason this is done this way is because you want to execute the test method on each item in the array. Just passing the test method to filter will (presumably) mess up the binding of the method.

我认为这样做的原因是您希望对数组中的每个项执行测试方法。仅仅将测试方法传递给筛选器将(可能)打乱方法的绑定。

That's why in your example:

这就是为什么在你的例子中:

/./

Generates an empty regex

生成一个空的正则表达式

/./.test

is the test method on that regex

那个regex上的测试方法是什么

/./.test.bind(new Regex(..))

binds that method to the requested method, and returns a new method that executes test where this is your supplied regex based on key.

将该方法绑定到所请求的方法,并返回一个新的方法,该方法执行基于key的测试。

It seems that it could have been written a lot more clear:

似乎可以写得更清楚些:

RegExp.prototype.test.bind(new RegExp(key, 'g'))