gpt4 book ai didi

javascript - 更改 RegExp 标志

转载 作者:可可西里 更新时间:2023-11-01 01:38:10 24 4
gpt4 key购买 nike

所以基本上我自己编写了这个函数,以便能够计算字符串中子字符串的出现次数:

String.prototype.numberOf = function(needle) {
var num = 0,
lastIndex = 0;
if(typeof needle === "string" || needle instanceof String) {
while((lastIndex = this.indexOf(needle, lastIndex) + 1) > 0)
{num++;} return num;
} else if(needle instanceof RegExp) {
// needle.global = true;
return this.match(needle).length;
} return 0;
};

该方法本身执行得相当好,并且基于 RegExp 和字符串的搜索在执行时间方面具有相当的可比性(在整个巨大的 Ray Bradbury 的“451 Fahrenheit”搜索所有“the”s 上都是 ~2ms)。

不过,让我感到困扰的是无法更改提供的 RegExp 实例的标志。如果没有将所提供的正则表达式的全局标志设置为 true,则在此函数中调用 String.prototype.match 是没有意义的,因为它只会记录第一次出现的情况。您当然可以在传递给函数的每个 RegExp 上手动设置标志,但我更喜欢能够克隆然后操作提供的正则表达式的标志。

令人惊讶的是,我不允许这样做,因为 RegExp.prototype.global 标志(更准确地说是所有标志)似乎是只读的。从那里注释掉第 8 行。

所以我的问题是:是否有一种不错的方法来更改 RegExp 对象的标志?

我真的不想做这样的事情:

if(!expression.global)
expression = eval(expression.toString() + "g");

有些实现可能不支持 RegExp.prototype.toString 并简单地从 Object.prototype 继承它,或者它可能是完全不同的格式。这似乎是一种糟糕的编码习惯。

最佳答案

首先,当 needle 是一个不匹配的正则表达式时,您当前的代码无法正常工作。即以下行:

return this.match(needle).length;

match 方法在没有匹配时返回 null。当(未成功)访问 nulllength 属性时,将生成 JavaScript 错误。这很容易修复:

var m = this.match(needle);
return m ? m.length : 0;

现在解决手头的问题。当您说 globalignoreCasemultiline 是只读属性时,您是正确的。唯一的选择是创建一个新的 RegExp。这很容易完成,因为正则表达式源字符串存储在 re.source 属性中。这是经过测试的函数修改版本,它纠正了上述问题并在 needle 尚未设置其 global 标志时创建一个新的 RegExp 对象:

String.prototype.numberOf = function(needle) {
var num = 0,
lastIndex = 0;
if (typeof needle === "string" || needle instanceof String) {
while((lastIndex = this.indexOf(needle, lastIndex) + 1) > 0)
{num++;} return num;
} else if(needle instanceof RegExp) {
if (!needle.global) {
// If global flag not set, create new one.
var flags = "g";
if (needle.ignoreCase) flags += "i";
if (needle.multiline) flags += "m";
needle = RegExp(needle.source, flags);
}
var m = this.match(needle);
return m ? m.length : 0;
}
return 0;
};

关于javascript - 更改 RegExp 标志,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5835469/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com