Javascript 是否有更干净的方法来删除非字母数字字符并替换空格?

Javascript 是否有更干净的方法来删除非字母数字字符并替换空格?,javascript,regex,Javascript,Regex,我想替换所有非字母数字字符,并用下划线替换空格。到目前为止,我已经使用多个正则表达式提出了这个问题,但有没有更“有效”的方法 "Well Done!".toLowerCase().replace(/\s/, '-').replace(/[^\w-]/gi, ''); 干得好 至少在其他语言中,调用正则表达式引擎代价高昂。我不确定JavaScript是否真的是这样,但下面是“C风格”的实现方式。我相信自己对其绩效进行基准测试将是一次宝贵的学习经验 var x = "Well Done!"; va

我想替换所有非字母数字字符,并用下划线替换空格。到目前为止,我已经使用多个正则表达式提出了这个问题,但有没有更“有效”的方法

"Well Done!".toLowerCase().replace(/\s/, '-').replace(/[^\w-]/gi, '');
干得好


至少在其他语言中,调用正则表达式引擎代价高昂。我不确定JavaScript是否真的是这样,但下面是“C风格”的实现方式。我相信自己对其绩效进行基准测试将是一次宝贵的学习经验

var x = "Well Done!";
var y = "";
var c;
for (var i = 0; i < x.length; i++)
{
    c = x.charCodeAt(i);
    if (c >= 48 && c <= 57 || c >= 97 && c <= 122)
    {
        y += x[i];
    }
    else if (c >= 65 && c <=  90)
    {
        y += String.fromCharCode(c+32);
    }
    else if (c == 32 || c >= 9 && c <= 13)
    {
        y += '-';
    }
}
$('#output').html(y);
var x=“干得好!”;
变量y=“”;
var c;
对于(变量i=0;i=48&&c=97&&c=65&&c=9&&c注意:我原以为我可以用一个正则表达式想出一个更快的解决方案,但我做不到。下面是我失败的方法(你可以从失败中学习)、性能测试的结果和我的结论

效率可以用很多方法来衡量。如果你想减少调用的函数数量,那么你可以使用一个正则表达式和一个函数来处理替换

([A-Z])|(\s)|([^a-z\d])

第一组将应用
toLowerCase()
,第二组将替换为
-
,第三组将不返回任何内容。我最初为组1和3使用了
+
量词,但考虑到文本的预期性质,删除它会加快执行速度。(感谢acheong87)

性能

我的方法表现最差:

Acheong87  fastest
Original   16% slower
Mine       53% slower

结论

就代码开发时间而言,您的方法是最有效的,与acheong87的方法相比,性能损失被代码的可维护性、可读性和复杂性降低所抵消。除非速度至关重要,否则我将使用您的版本


我向正则表达式中添加的可选匹配越多,性能损失就越大。除了函数缩减之外,我想不出我的方法有什么好处,但这被
if
语句和复杂性增加所抵消。

您不需要
toLowerCase()
,您指的是破折号
-
,而不是下划线
?您可以使用函数作为第二个参数来决定对任何给定匹配项的替换内容:。这将避免对字符串进行两次检查。这是否比对短字符串的许多JS函数调用更有效值得怀疑。(我的直觉告诉我“不”,但我不能被激怒去做一个jsperf。)无论如何,你的代码是有效的,所以我不确定这是一个完全合适的问题。比如,什么能让答案“正确”?除了“不同”,或者是第一个,或者你出于某种原因喜欢它。@millimoose似乎使用函数参数是一个不错的选择,我真正检查的是是否有一些更“智能”的正则表达式可以让我同时做这两件事:)@htmlr这是一个不同的选项。我认为在你的情况下,可读性和性能都会更差。你在做两件不同的事情,做两个不同的调用就足够了。因为Javascript有re文本,它可能不会那么昂贵。re可能是与JS源代码一起编译的,而不是每次调用它。你的乐趣Action与op不太匹配。特别是他想要替换空白,但你只是在替换空格。
\w
替换空格、制表符和换行符。@DanielGimenez-谢谢。我意识到了这一点,但认为转换是为了创建slug。无论如何,我肯定应该提到它。事实证明大部分字符都是正则表达式中的空格被连续地放在ASCII中;不确定JavaScript是否包含
\f
\v
作为空格字符,但是答案已经更新为包含所有。很好;感谢基准测试;我不知道这个站点。我想知道如果你颠倒过来会有什么区别交替原子的顺序(因为空格是最稀有的,大写字母是第二稀有的,小写字母是最常见的)。此外,上述方法可能效率低下的原因之一是它需要回溯。我从精神上看你试图最小化替换,但
+
强制执行“失败匹配”在测试下一个alternation atom之前发生,而没有
+
,替换是立即进行的。我不确定JS引擎中的底层代码是什么样子,但我想知道替换时间是否与字符数而不是调用数有更大的关系。我刚刚编辑了您的测试以给出这些修改很简单;嗯,性能优势并没有我想象的那么大。事实上,这是一个值得学习的好例子。(现在编辑我的答案,将regex空格字符也包括在内,即
[\f\n\r\t\v]
@acheong87,您在这两方面都是对的。示例文本的性质和实际使用使得
+
在性能方面效率低下。如果我们希望大写字母更频繁,更改顺序也会有所帮助。
Acheong87  fastest
Original   16% slower
Mine       53% slower