我经常遇到格式错误的 utf-8 字符会破坏我的代码。我已经阅读了有关 stackoverflow 的一些(不是全部)相关问题/答案,但没有特定于 Raku/perl6。有没有一种快速的方法可以从字符串中删除这些讨厌的字符? “https://docs.raku.org/language/regexes#Predefined_character_classes ”中的预定义字符类不会这样做:
示例:来自 REPL:
> say "â " ~~ /\w/ # you have to have a space following the "a" with "^" for it to work
「â」
> say "�" ~~ /\w/ # without the space, the character doesn't look normal
Malformed UTF-8 at line 1 col 6
> say "â ".chars # looks like 2 chars, but it says 1 char
1
> say "â ".comb.[0] # strange, the pesky char makes the space precede the cursor as I type
â
> say "â".comb.[0 ] # strange, the pesky char makes the space precede the cursor as I type
â
> say "â".comb.[0] # there is a space following ']' or it won't work
â
> say "â".comb.[0 ] # very strange, must have space before ']'
â
> say "â".comb
(â)
> say "â".comb.[0] .ord # # same here, very strange, it makes space precede the cursor
226
> my $a = Buf.new(226)
Buf:0x<E2>
> say $a.decode
Malformed termination of UTF-8 string
in block <unit> at <unknown file> line 1
> say $a.decode('utf8-c8')
xE2
> for @$a { say $_.chr; }
â
> say (@$a).elems
1
> say "â " ~~ / <alpha> / # again, must have space in the quote
「â」
alpha => 「â」
> say "â " ~~ / <cntrl> /
Nil
这是非常麻烦的。如何删除这些非 utf8 字符?对于所有良好的 utf-8 字符或作为模型公民的良好 ASCII 字符,是否有预定义的字符类?
最佳答案
希望有人会有更好的答案。同时...
您的问题中有几件非常不同的事情。
Is there a fast method to find and remove/replace non-ASCII or malformed utf8 characters?
应该有一个很好的,明显的,相当简单的:
say .decode: replacement => '�'
given $buf-that's-supposed-to-be-utf8
这应该以与普通
slurp
相同的方式解码确实如此,除了当它遇到“格式错误的 UTF-8”时不要仅仅放弃解码,它应该只用您指定的替换字符替换格式错误的数据并尽可能继续。不幸的是(据我所知)由于 rakudo/moarvm 中的错误,这不起作用,如我对 decode with replacement does not seem to work 的回答中所述。 .
我在写 SO 时没有提出问题。您的新 SO 提示我提交了两个错误报告:
.decode
's replacement
option didn't work in Rakudo v2019.03.01 and presumably still doesn't #3509 对 error message: Malformed UTF-8 的回答中给出了其他一些选项。 .
我在您尝试过的 repl 示例中看到
.decode('utf8-c8')
.就目前而言,这可能是您在 raku 中的最佳选择。如果以上都没有帮助,我认为您现在无法使用外部工具在文件到达 raku 之前对其进行预处理。
Is there a predefined character class for all good utf-8 chars
utf8 数据不是字符。这只是字节。数据对字符进行编码,或者至少它应该对字符进行编码,但是在您的脑海中将编码和字符分开是非常重要的。
如果你知道老式电报的工作原理,就是这样。有一个字符的消息。然后 morse code用于传输它。它们是非常不同的东西。
当您看到“格式错误的 UTF-8”或类似内容时,这意味着解码器因数据的某些部分(字节)而阻塞。它们作为角色没有任何意义。这就像莫尔斯电码不遵循莫尔斯电码规则。
这样的数据充其量是令人困惑的废话,最坏的情况是危险的废话。 Unicode 标准要求在您可以对其进行任何操作之前将其完全消除。
显而易见的友好解决方案是按照您的要求用用户指定的替换字符替换废话。相比之下,正则表达式字符类既是错误的工具,也为时已晚。
示例:来自 REPL
这是另一个完整的蜡球。
有:
即使我们的系统和你我都在做我们应该做的事情,这种复杂性仍然存在。所以,当然,光标和其他问题有些不对劲,但我不会尝试用这个答案来确定这一点,因为与我在上面回答的问题的第一部分不同,这与 raku/do 没有关系.
关于regex - Raku 有没有一种快速的方法来查找和删除/替换非 ASCII 或格式错误的 utf8 字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60365292/