删除字符串中的非 ascii 字符

2022-08-30 05:27:13
var str="INFO] :谷���新道, ひば���ヶ丘2丁���, ひばりヶ���, 東久留米市 (Higashikurume)";

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

表示 str 仅包含“信息](东库鲁梅)”;


答案 1

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

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

答案 2

它也可以通过积极的删除断言来完成,如下所示:

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

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

我称之为“删除的肯定断言”,因为“肯定”断言表示要删除哪些字符,而“否定”断言表示不删除哪些字母。在许多情况下,如前所述,否定断言可能对读者更具启发性。circumflex“”表示“not”,范围表示“ascii”,因此两者一起表示“not ascii”。^\x00-\x7F

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

对于只关心英语的英语使用者来说,这是一个很好的解决方案,也是对原始问题的一个很好的答案。但在更一般的背景下,人们不能总是接受假设“所有非ascii都是坏的”的文化偏见。对于使用非 ascii 但偶尔需要剥离的上下文,Unicode 的肯定断言更合适。

当字符串的“length”属性为正(非零)但看起来像(即打印为)空字符串时,嵌入在字符串中的零宽度非打印字符的一个很好的指示。例如,我在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 字符的家族,这些字符由文字处理器插入到文档中,然后进入数据字段。最常见的是,这些符号出现在文档的末尾。零宽度空间可能由 CK 编辑器 (CKEditor) 插入。"%E2%80%8B"

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://en.wikipedia.org/wiki/Left-to-right_mark

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

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