regex - Raku 有没有一种快速的方法来查找和删除/替换非 ASCII 或格式错误的 utf8 字符?

标签 regex char raku

我经常遇到格式错误的 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
  • decoder replacement options didn't work in Rakudo v2019.03.01 and presumably still don't #1245


  • 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

    这是另一个完整的蜡球。

    有:
  • 您的(您的)本地系统上的终端使用的编码;
  • 当您使用本地系统时,您看到呈现的字符以及光标的指示;
  • 从 repl 显示复制时,剪切/粘贴缓冲区中有什么;
  • 当您粘贴到 SO 问题的编辑窗口时,您的浏览器对该缓冲区做了什么;
  • 当您单击“发布您的问题”按钮以及当 SO 呈现您的问题时,SO 的服务器如何处理编辑窗口的内容;
  • 当我查看您的 SO 问题时,我的本地系统、浏览器、终端、剪切/粘贴缓冲区等正在做什么;

  • 即使我们的系统和你我都在做我们应该做的事情,这种复杂性仍然存在。所以,当然,光标和其他问题有些不对劲,但我不会尝试用这个答案来确定这一点,因为与我在上面回答的问题的第一部分不同,这与 raku/do 没有关系.

    关于regex - Raku 有没有一种快速的方法来查找和删除/替换非 ASCII 或格式错误的 utf8 字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60365292/

    相关文章:

    javascript 将字符串视为字符数组 - 如何更改它?

    java - 如何重新排列字符以使单词存在于字典中?

    raku - 我可以在 Nil 上调用任何方法,这感觉不对

    raku - 如何打印对象,输入 nqp

    javascript - RegExp - 如何检查字符串中的两个括号

    ruby - 如果使用 Ruby 的页面上字符串 A 出现在字符串 B 之前,则匹配的正则表达式

    c++ - 取消分配从函数返回的 char*

    macos - 为什么在 MacOS Big Sur 上使用 Pakku 时会崩溃 'Cannot locate native library libarchive.13.dylib'

    regex - Nginx位置代字号

    java - 解析特殊格式的字符串