【问题标题】:Translate Unicode mathematical bold/italic characters to latin-1 in Perl在 Perl 中将 Unicode 数学粗体/斜体字符转换为 latin-1
【发布时间】:2020-06-17 15:03:37
【问题描述】:

Unicode 对粗体或斜体字符有单独的字符,例如U+1D43B 是斜体 H。有关这些列表,请参阅 https://unicode-search.net/unicode-namesearch.pl?term=mathematical

当用户从电子教科书中复制化学式时,他们实际上可能是在复制这些字符而不是 Latin-1 字符,因此他们复制的是“U+1D43B U+2082 U+1D442”而不是“H2O” .当他们将其粘贴到搜索表单中时,它看起来像 H2O。但他们不会得到任何结果,因为它不是拉丁字符。

所以,我需要将这些字符翻译成 Perl 中的 Latin-1 字符。 Text::Unidecode 库似乎无法识别这些。

我尝试使用音译,

 y/\x{1d434}-\x{1d467}/A-Za-z/

但这似乎根本不起作用。

有没有办法在 unicode 字符范围内使用翻译运算符?或者有没有图书馆可以做到这一点?

【问题讨论】:

  • 不,不,不。粗体和斜体没有特殊字符,这在 Unicode 原则中明确定义。 MATHEMATICAL ITALIC H 具有特定语义,不应用于 H2O。顺便说一句,您应该检查/google NFKC 或 NFKD(Unicode 兼容规范化),它们应该将这个(可能还有下标 2 等)转换为 normal 字符。
  • 我同意不应该那样使用它。但其他人是,这正在影响用户。
  • 无论如何,对于搜索,您应该规范化文本(这不是您可能得到的唯一惊喜)。 perldoc.perl.org/Unicode/Normalize.html

标签: perl unicode


【解决方案1】:

实际上它确实有效。

use open ':std', ':encoding(UTF-8)';

my $s = "\N{U+1D43B}\N{U+2082}\N{U+1D442}";
say sprintf "%vX", $s;
$s =~ y/\x{1d434}-\x{1d467}/A-Za-z/;
say sprintf "%1\$vX %1\$s", $s;

输出:

1D43B.2082.1D442
48.2082.4F H₂O

也许您实际上没有您描述的三个字符的字符串?也许您使用 UTF-8 编码的文本?

【讨论】:

    【解决方案2】:

    实际上,音译运算符确实有效。这是确保变量被正确编码的问题。

    $str =~ y/\x{1d400}-\x{1d6a3}/A-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-zA-Za-z/r
      =~ y/\x{1d7ce}-\x{1d7ff}/0-90-90-90-90-9/r );
    

    似乎有效。

    但是,Unicode::Normalize::NDKD 效果更好。谢谢。

    【讨论】:

      猜你喜欢
      • 2021-11-30
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-05
      • 1970-01-01
      • 1970-01-01
      • 2015-03-07
      相关资源
      最近更新 更多