寻找 Unicode 字符串的十六进制代码

4

我有一个Unicode字符串,除了常规字符外,还包含一些奇怪的字符。我已经找到了其中一些字符的“UTF-16(十六进制)”编码,并使用一些简单的正则表达式将它们移除,例如:

$text =~ s/(\s+\x{200C}+|\x{200C}+\s+)/ /g;

上述行是为了去除不必要的“零宽度非连接器空格”。 但我在去除剩下的字符方面遇到了一些困难。我想知道是否有工具或命令,可以将您的Unicode字符串传递给它,并返回相应的“UTF-16(十六进制)”编码。 所以,基本上我想用我的字符串(其中包含奇怪的字符)来提供它,并获取字符的“UTF-16(十六进制)”编码,以便能够编写一些正则表达式来删除它们。 我必须指出,我的文本大多是波斯语和阿拉伯语,而不是英语。
我得到了上述问题的答案,但我仍然存在整个问题。 实际上,我有一些像“阿拉伯语元音”这样的字符,我想从我的字符串中删除它们。由于我已经找到了这些字符的Perl代码,我编写了一行代码来删除它们:
$text =~ s/\x{0618}\x{0619}\x{0621}\x{064B}\x{064C}\x{064D}\x{064E}\x{064F}\x{0650}\x{0651}\x{0652}\x{0653}\x{0654}\x{0655}\x{0656}\x{0657}\x{0658}\x{0659}\x{065A}\x{065B}\x{065C}\x{065D}\x{065E}\x{FC5E}\x{FC5F}\x{FC60}\x{FC60}\x{FC61}\x{FC62}\x{FE80}//g;

但奇怪的是并不适用于所有情况。例如,“阿拉伯Kasra(\x {0650})”应该被检测并替换为这一行代码,但它没有被替换。 我已经提到对于下面一行中的字符它可以工作:
\x{064B}\x{064C}\x{064D}\x{064E}\x{064F}\x{065A}\x{065B}\x{065C}\x{065D}\x{065E}\x{FC5E}\x{FC5F}\x{FC60}\x{FC60}\x{FC61}\x{FC62}\x{FE80}

对于其他人来说可能不一样:

\x{0618}\x{0619}\x{0621}\x{0650}\x{0651}\x{0652}\x{0653}\x{0654}\x{0655}\x{0656}\x{0657}\x{0658}\x{0659}

有什么想法吗?

谢谢,

1个回答

4
UTF-16le和UTF-16be编码的U+200C是"\x0C\x20""\x20\x0C",而不是"\x{200C}"。这与UTF-16无关。您只需要字符编号的十六进制表示。 (实际上这甚至与Unicode无关。)
  • Hex of every character:

    print(sprintf("%v04X", $str), "\n");
    
  • Sometimes hex sometimes octal of non-ASCII and non-printable ASCII characters:

    use Data::Dumper qw( Dumper );
    local $Data::Dumper::Useqq = 1;
    local $Data::Dumper::Terse = 1;
    local $Data::Dumper::Indent = 0;
    print(Dumper($str), "\n");
    
  • Hex of non-ASCII and non-printable ASCII characters:

    my $lit = qq{"\Q$str\E"};
    $lit =~ s/([^\x20-\x7E])/ sprintf('\\x{%04X}', ord($1)) /eg;
    print("$lit\n");
    

亲爱的ikegami,感谢您的回复。它起作用了,现在打印字符代码。但是现在我面临另一个问题。我有一些字符,例如“ARABIC KASRA”,其代码为\x{0650},我在脚本中有一个正则表达式来从字符串中删除它。但奇怪的是它不起作用,这个字符仍然存在于字符串中。我在我的第一篇帖子中添加了一些描述这种情况更清楚的行。 - amin
你在s/\x{0618}\x{0619}\x{0621}.../.../中忘记了方括号。 - ikegami
哦,对不起,我犯了这个错误。 - amin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接