删除字符串中的非ASCII字符


89
var str="INFO] :谷���新道, ひば���ヶ丘2丁���, ひばりヶ���, 東久留米市 (Higashikurume)";

我需要从字符串中删除所有非ASCII字符,

表示str仅包含“ INFO](Higashikurume)”;

Answers:


228

ASCII的范围是0到127,因此:

str.replace(/[^\x00-\x7F]/g, "");

8
@AlexanderMills搜索ascii表-您可以看到只有值从零到127的字符才有效。(0x7F是127的十六进制)。此代码匹配不在ascii范围内的所有字符并将其删除。
Zaffy

30

也可以使用肯定的删除声明来完成此操作,如下所示:

textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");

这使用unicode。在Javascript中,当为正则表达式表示unicode时,用转义序列指定字符,\u{xxxx}但也'u'必须存在标志;注意正则表达式带有标志'gu'

我将其称为“删除的肯定断言”,因为“肯定”断言表示要删除的字符,而“否定”断言表示不删除的字母。在许多情况下,如先前答案中所述,否定性主张可能对读者更具启发性。抑扬符“ ^”表示“不”,范围\x00-\x7F表示“ ascii”,因此两者一起说“ not ascii”。

textContent = textContent.replace(/[^\x00-\x7F]/g,"");

对于只关心英语的讲英语的人来说,这是一个很好的解决方案,并且对于原始问题也提供了很好的答案。但是在更笼统的背景下,人们不能总是接受假定“所有非ASCII都是不好的”的文化偏见。对于使用非ascii但偶尔需要删除的上下文,使用Unicode的肯定断言比较合适。

当字符串的“长度”属性为正(非零)但看起来像(即打印为)空字符串时,则在字符串中嵌入了零宽度,非打印字符的一个好兆头。例如,我在Chrome调试器中显示了名为“ textContent”的变量:

> textContent
""
> textContent.length
7

这促使我想查看该字符串中的内容。

> encodeURI(textContent)
"%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B%E2%80%8B"

字节序列似乎属于一些Unicode字符的系列,这些字符由文字处理器插入文档中,然后找到进入数据字段的方式。最常见的是,这些符号出现在文档的末尾。零宽度空格"%E2%80%8B"可能由CK-Editor(CKEditor)插入。

encodeURI()  UTF-8     Unicode  html     Meaning
-----------  --------  -------  -------  -------------------
"%E2%80%8B"  EC 80 8B  U 200B   ​  zero-width-space
"%E2%80%8E"  EC 80 8E  U 200E   ‎  left-to-right-mark
"%E2%80%8F"  EC 80 8F  U 200F   ‏  right-to-left-mark

关于这些的一些参考:

http://www.fileformat.info/info/unicode/char/200B/index.htm

https://zh.wikipedia.org/wiki/从左到右标记

请注意,尽管嵌入字符的编码为UTF-8,但正则表达式中的编码不是。尽管字符以UTF-8的三个字节(在我的情况下)嵌入字符串中,但正则表达式中的指令必须使用两字节Unicode。实际上,UTF-8的长度最多为四个字节。它比Unicode紧凑,因为它使用高位(或多个)来转义标准ascii编码。解释如下:

https://zh.wikipedia.org/wiki/UTF-8


3
textContent = textContent.replace(/[\u{0080}-\u{FFFF}]/gu,"");不适用于IE(至少是IE 11)。它失败并显示错误:SCRIPT5021字符集中的范围无效
Andrey Sorich,

14

您可以使用以下正则表达式替换非ASCII字符

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

但是,请注意,空格,冒号和逗号都是有效的ASCII,因此结果为

> str
"INFO] :, , ,  (Higashikurume)"

我对regex不太满意,但是知道.replace()方法将要替换的东西替换为第二个参数,如.replace('replace this text','with this text')。因此,该部分的内容与此相反,并保留了ASCII字符并删除了其他字符。谢谢。
NicoM 2014年

2
@NicoM中的字符[]表示任何字符,但[^]表示相反的字符-匹配括号中没有的任何字符。
扎菲2014年

10

这些答案均不能正确处理制表符,换行符,回车符,并且某些不能处理扩展的ASCII和unicode。这将保留制表符和换行符,但会删除控制字符和ASCII集中的所有内容。点击“运行此代码段”按钮进行测试。有一些新的javascript即将发布,因此在将来(2020年或以后),您可能需要做,\u{FFFFF}但尚未完成

console.log("line 1\nline2 \n\ttabbed\nF̸̡̢͓̳̜̪̟̳̠̻̖͐̂̍̅̔̂͋͂͐l̸̢̹̣̤̙͚̱͓̖̹̻̣͇͗͂̃̈͝a̸̢̡̬͕͕̰̖͍̮̪̬̍̏̎̕͘ͅv̸̢̛̠̟̄̿i̵̮͌̑ǫ̶̖͓͎̝͈̰̹̫͚͓̠̜̓̈́̇̆̑͜ͅ".replace(/[\x00-\x08\x0E-\x1F\x7F-\uFFFF]/g, ''))


这是一个很好的正则表达式,但是它也删除了重音符号和表情符号。我不确定如何改进此正则表达式以涵盖这些情况。
Julio Vedovatto

为寻找可能的解决办法,以消除角window.atob和DOMSanitizer.bypassSecurity ...无效字符(可能是80%,\ uFFFF或原因不明的空格)转换为Base64的时候,这是一个工作的解决方案
B.莱昂

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.