Как представить символы Unicode в шаблоне регулярных выражений ASCII? - PullRequest
1 голос
/ 21 января 2011

RegEx flavor: wxRegEx в C ++.

Одна из строк, которые мне нужно сопоставить, содержит символы типа '' (U + 2026, Горизонтальный эллипсис), который переводится в \ 205 при вставке в Emacs и ' » '(U + 00BB, прямоугольная кавычка, указывающая вправо), которое остается » при вставке в Emacs (режим исходного кода ASCII).

В самом шаблоне регулярных выражений я пытался представить '' как \ 205 и \\ 205 , но безрезультатно.

Как правильно решить эту проблему?

Обновление : в документации wxRegEx говорится, что для представления символа Unicode вы используете \ uwxyz (где wxyz - ровно четыре шестнадцатеричных цифры), символ Unicode U + wxyz в местном порядке байтов.

Я пробовал это, но по какой-то причине у меня это не работает (пока).

1 Ответ

2 голосов
/ 21 января 2011

Это зависит от языка. Во многих языках нет необходимости экранировать не-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 в исходный код. Если вам нужно выяснить, чтобы избежать вещей, ну, это гораздо менее удобно.

Если вы собираетесь использовать escape-символы, то, как вы указываете не ASCII символически, также зависит от языка. В Java вы можете использовать запрашивающий препроцессор Java через \uXXXX:

String s = "e\u0301le\u0300ve";

хотя я не рекомендую этот способ. Если он будет использоваться в шаблоне, вы можете отложить интерполяцию, которая является одновременно более чистой и запутанной:

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

Этот второй механизм избавляет вас от попыток выяснить, что это такое после того, как препроцессор Java справился с этим (вы не можете использовать \u0022, но можете использовать \\0022), но затем он испортит ваш шаблон .CANON_EQ flag.

Большинство других языков имеют более простой способ сделать это, чем Java - который также настаивает на уродливом UTF-16, если вы не используете java -encoding UTF-8 в качестве источника. Жесткое кодирование суррогатов 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, но многие этого не делают.

...