如何用ASCII正则表达式模式表示Unicode字符?

时间:2011-01-20 22:58:20

标签: regex unicode escaping wxwidgets ascii

RegEx flavor:C ++中的wxRegEx

我需要匹配的其中一个字符串包含“ ... ”(U + 2026,水平省略号)等字符,当粘贴到Emacs时转换为 \ 205 '»'(U + 00BB,右指双角引号)粘贴到Emacs时仍为»(ASCII源代码模式)。

在正则表达式模式中,我尝试将“ ... ”表示为 \ 205 \\ 205 无效。

解决此问题的正确方法是什么?

更新:wxRegEx文档声明要表示Unicode字符,您使用 \ uwxyz (其中wxyz正好是四个十六进制数字)Unicode字符 U + wxyz 在本地字节排序中。

我试过了,但由于某种原因,它对我来说还不起作用。

1 个答案:

答案 0 :(得分:2)

这取决于语言。在许多语言中,不需要转义非ASCII,但您可能必须告诉编译器源是什么编码。例如:

$ java -encoding UTF-8 SomeThing.java

$ perl -Mutf8 somescript

虽然使用Perl,Python和Ruby之类的东西,但您可以将声明放在文件中,使其向上兼容ASCII。例如:

#!/usr/bin/perl

use utf8;
use strict;
use warnings;
use autodie;

my $s = "Où se trouve mon élève?";

if ($s =~ /élève/) { ... }

# although of course this also works fine:

while ($s =~ /\b(\w+)\b/g) {
     print "Found <$1>\n";  
}

这是最简单的方法,我强烈推荐它:只需在源代码中输入真正的UTF-8字符即可。如果你必须想出逃避的事情,那么它就不那么方便了。

如果要使用转义符,那么,如何以符号方式指定非ASCII也会因语言而异。在Java中,您可以通过\uXXXX使用asquerous Java预处理器:

String s = "e\u0301le\u0300ve";

虽然我不推荐这种方式。如果它将在一个模式中使用,你可以延迟插值,同时更清洁和更麻烦:

String s = "e\\u0301le\\u0300ve";

第二种机制使您免于尝试在Java预处理器使用它之后弄清楚它是什么(您不能使用\u0022但可以使用\\0022),但随后它拧紧你的Pattern.CANON_EQ标志。

大多数其他语言都有一种更简单的方法来实现Java - 除非你使用java -encoding UTF-8来源,否则它也坚持使用丑陋的UTF-16。硬编码UTF-16代理人绝对是愚蠢的。不要这样做!!

在Perl中你可以使用:

my $s = "e\x{301}le\x{300}ve";  # NFD form
my $s = "\xE9l\xE8ve";          # NFC form

但你也可以象征性地命名它们

use charnames qw< :full >;
my $s_as_NFD = "e\N{COMBINING ACUTE ACCENT}le\N{COMBINING GRAVE ACCENT}e";
my $s_as_NFC = "\N{LATIN SMALL LETTER E WITH ACUTE}l\N{LATIN SMALL LETTER E WITH GRAVE}ve";

如果您愿意,可以缩短最后一个:

use charnames qw< :full latin >;
my $s_as_NFC = "\N{e WITH ACUTE}l\N{e WITH GRAVE}ve";

所有这些都比你的代码中的硬编码神奇数字要优越得多。

这一切都假设您的语言支持Unicode,但很多都不支持。