使用正则表达式删除所有特殊字符

312

我想要一个正则表达式,可以从字符串中删除所有特殊字符。我正在尝试类似这样的操作,但它在IE7中无法工作,虽然在Firefox中可以。

var specialChars = "!@#$^&%*()+=-[]\/{}|:<>?,.";

for (var i = 0; i < specialChars.length; i++) {
  stringToReplace = stringToReplace.replace(new RegExp("\\" + specialChars[i], "gi"), "");
}

提供正则表达式的详细描述会更有帮助。


22
把这个东西改成白名单会更好,不要使用黑名单。那么你只需要写[a-z]|[0-9]|\s就可以了。 - Ape-inago
1
有任何脚本错误吗?你进行了调试吗?否则在JavaScript代码中加入try...catch块。 - Kangkan
1
@ Ape-inago,你能否请更详细地解释一下正则表达式给我吗? - Timothy Ruhle
4
请定义“特殊字符”!对于你来说,“風”是特殊的吗?(思考这一点,你会理解@Ape-iango的观点。) - deceze
8
我不认为这里有人有任何冒犯的意思。我以前尝试过将其列入黑名单,但由于总会有一些小问题“被偷懒”而通过(如deceze举的例子),我曾因此受到伤害。最终,正确的方法更多地关乎于你为什么要这样做。 - Ape-inago
显示剩余5条评论
11个回答

755
var desired = stringToReplace.replace(/[^\w\s]/gi, '')

正如评论中提到的那样,更容易将其作为白名单来处理-替换不在安全列表中的字符。

插入符号 (^) 表示集合 [...] 的否定,gi 表示全局和忽略大小写 (后者有点多余,但我想提一下),在此示例中的安全列表包括数字、单词字符、下划线 (\w) 和空格 (\s)。


80
这个解决方案不适用于非英语符号,例如"Їжак"。 - Seagull
8
您可以使用大写的 \W 代替 ^\w。 \W:匹配任何非单词字符,等同于 [^A-Za-z0-9_]。https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions - delkant
5
接受带有重音的单词,就像葡萄牙语一样,请执行以下操作:stringToReplace.replace(/[^A-zÀ-ú\s]/gi, '') - alansiqueira27
4
为了支持大多数欧洲语言(挪威语、瑞典语、德语、葡萄牙语、西班牙语),可以使用以下代码:stringToReplace.replace(/[^\w\s\xc0-xff]/gi, '')。 如果需要支持其他语言,则可以使用Unicode范围。 参见:https://dev59.com/OHVC5IYBdhLWcg3w51lv。 - Eskil Mjelva Saatvedt
3
对我而言最好的选择是没有口音或特殊符号。甚至连空格都不要,我已经去除了 \s - tatsu
显示剩余4条评论

168

请注意,如果你仍然想要排除一个集合,包括斜杠和特殊字符等内容,你可以按照以下方式进行操作:

var outString = sourceString.replace(/[`~!@#$%^&*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');

请特别注意,在正则表达式中如果想要包含“减号”字符,需要像后面这个组一样使用反斜杠对其进行转义。如果不进行转义,它也会选择0-9,这可能是不希望的。


20
很棒的解决方案!被采纳的答案只适用于英语,这个方案适用于任何语言(据我所检查的)。谢谢 :) - Ronen Ness
1
@knutole,将字符集部分前面的?删除。这会列出您想要删除的字符,因此从剥离中排除它将固有地包含在最终结果中。 - noinput
这个很好用,适用于任何语言,只需要添加您想要替换的字符,就可以了。谢谢。 - Kevin Ramirez Zavalza
我该如何在搜索输入上实现这个功能?我该如何使用正则表达式测试输入? - PhilosophOtter
1
顺便提一下,不需要转义 {}。例如:var outString = sourceString.replace(/[\~!@#$%^&*()_|+-=?;:'",.<>{}[]\/]/gi, '');` - Aldis

31

纯JavaScript正则表达式无法处理Unicode字符

不要使用[^\w\s],这将移除带有重音符号的字母(如àèéìòù),更不用说来自西里尔文或汉语等语言的字母将被完全移除。

你真的不想把这些字母和所有特殊字符一起删除。你有两个选择:

  • 在你的正则表达式中添加所有你不想删除的特殊字符,例如:[^èéòàùì\w\s]
  • 查看xregexp.com。 XRegExp通过\p{...}语法添加了对Unicode匹配的基本支持。

var str = "Їжак::: résd,$%& adùf"
var search = XRegExp('([^?<first>\\pL ]+)');
var res = XRegExp.replace(str, search, '',"all");

console.log(res); // returns "Їжак::: resd,adf"
console.log(str.replace(/[^\w\s]/gi, '') ); // returns " rsd adf"
console.log(str.replace(/[^\wèéòàùì\s]/gi, '') ); // returns " résd adùf"
<script src="https://cdnjs.cloudflare.com/ajax/libs/xregexp/3.1.1/xregexp-all.js"></script>


3
对于国际化来说这很重要,我不知道JS正则表达式没有考虑UTF-8。 - LessQuesar
1
你不能将所有有效的UTF-8字符放入变量str中。 - Seagull
@Seagull 是的,但是如果你不编写全球兼容的应用程序,你可以实用主义地只放置当前本地化的有效UTF-8字母列表。在我的情况下,对于意大利语言只有很少的字母。 - freedev

14

使用\W[a-z0-9]这样的正则表达式无法处理非英语语言,例如中文等。

最好在正则表达式中使用所有特殊字符,并将它们从给定的字符串中排除。

str.replace(/[~`!@#$%^&*()+={}\[\];:\'\"<>.,\/\\\?-_]/g, '');

11

第一种解决方案并不适用于任何UTF-8字母表,例如Їжак这样的文本将被切断。我已经成功创建了一个函数,它不使用RegExp并且利用JavaScript引擎中良好的UTF-8支持。这个想法很简单,如果一个符号在大写和小写时相等,则它是一个特殊字符,唯一的例外是空格。

function removeSpecials(str) {
    var lower = str.toLowerCase();
    var upper = str.toUpperCase();

    var res = "";
    for(var i=0; i<lower.length; ++i) {
        if(lower[i] != upper[i] || lower[i].trim() === '')
            res += str[i];
    }
    return res;
}

更新: 请注意,此解决方案仅适用于存在大小写字母的语言。对于像中文这样不存在大小写字母的语言,此方法将无效。

更新2: 当我在处理模糊搜索时,我想到了原始解决方案。如果您也想删除特殊字符以实现搜索功能,则有更好的方法。使用任何一个转换音标库,它将为您生成仅由拉丁字符组成的字符串,然后简单的正则表达式就可以轻松删除特殊字符。(这同样适用于中文,并且您还将获得副作用,如将Tromsø等于Tromso)。


很好,喜欢这个答案!我用它来创建一个有效的文件名,并扩展了您的解决方案以删除空格(与Linux / Unix兼容)并允许数字。因此,我扩展了if语句(涉及jQuery):如果(str [i]!==' ' &&(lower [i]!= upper [i] || lower [i] .trim()=== '' || $ .isNumeric(str [i]))) - Jonny
在许多语言中,没有大写字母...因此该函数将把有效输入视为特殊字符。 - Yair Levy
中文字符就是其中一个会被剥离的例子。 - lethek
当我创建这个解决方案时,不幸的是,我没有考虑到像中文这样的语言。必须提出解决方案,因为以前的答案也行不通。 - Seagull

2
我使用RegexBuddy调试我的正则表达式,它几乎包含了所有语言,非常有用。然后将其复制/粘贴到目标语言中。这是一个很棒的工具,价格也不贵。
所以我复制/粘贴了你的正则表达式,你的问题是[,]在正则表达式中是特殊字符,因此需要对它们进行转义。因此,正则表达式应该是:/!@#$^&%*()+=-[\x5B\x5D]\/{}|:<>?,./im。

2

str.replace(/\s|[0-9_]|\W|[#$%^&*()]/g, "")我曾经这样做。 但是有些人做得更简单,例如:str.replace(/\W_/g,"");


你的方法中大部分都是多余的,因为\W已经包含了一些字符。但是为什么要过滤数字呢?它们并不是特殊字符。 - Sebastian Simon

1

除了字母和数字之外,删除所有字符:

str.replace(/[^\p{L}\d]+/gu, '')

如果你需要留空格的话:
str.replace(/[^\p{L}\d\s]+/gu, '')

0

@Seagull的回答(https://dev59.com/a2855IYBdhLWcg3wYjOF#26482552)看起来不错,但是当有一些特殊的(土耳其)字符时,结果中会出现未定义的字符串。请参见下面的示例。

let str="bənövşəyi пурпурный İdÖĞ";

我稍微改进了它并补丁化了未定义检查。

function removeSpecials(str) {
    let lower = str.toLowerCase();
    let upper = str.toUpperCase();

    let res = "",i=0,n=lower.length,t;
    for(i; i<n; ++i) {
        if(lower[i] !== upper[i] || lower[i].trim() === ''){
            t=str[i];
            if(t!==undefined){
                res +=t;
            }
        }
    }
    return res;
}

哇,这是一个非常棒的想法。我会以不同的方式实现它。但是它不支持没有大写字母的语言,如希伯来语、阿拉伯语和中文等。 - oriadam

0
text.replace(/[`~!@#$%^*()_|+\-=?;:'",.<>\{\}\[\]\\\/]/gi, '');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接