Как я могу преобразовать сложное двоичное регулярное выражение Perl в C # или PowerShell? - PullRequest
3 голосов
/ 09 июля 2009

Это двоичное регулярное выражение Perl, найденное в http://www.w3.org/International/questions/qa-forms-utf-8.en.php, соответствует документам UTF-8 без заголовка спецификации UTF-8:

$field =~
m/\A(
 [\x09\x0A\x0D\x20-\x7E]            # ASCII
 | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
 |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
 | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
 |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
 |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
 | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
 |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
)*\z/x;

Мне это нужно, потому что я работаю над PowerShell, эквивалентным 'grep -I' , и часть этого связана с обнаружением кодировки текста.

Но как мне переписать это в C # или PowerShell? Или, другими словами, в синтаксисе ".Net Regex"?

РЕДАКТИРОВАТЬ: Нашел этот http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/6a81be63-e6da-4156-a5bf-8b9782a1ac40 вопрос о том же Regex всех вещей. Краткий ответ кажется, что это невозможно сделать с помощью .Net, так как .Net не поддерживает двоичные регулярные выражения.

Ответы [ 4 ]

1 голос
/ 09 июля 2009

Вероятность того, что в последовательности нет недопустимых символов UTF-8, может рассматриваться как UTF-8. Так как RegExps предназначены для текста в .Net, а не для байтовых массивов, вот решение, не являющееся регулярным выражением, которое должно работать. Лично я предпочел бы использовать это в качестве резервного механизма (например, mycommand -autodetect) и предлагать параметры конвейера, которые позволяют заданные пользователем кодировки.

       string result=String.Empty;
        Encoding ae = Encoding.GetEncoding(
              Encoding.UTF8.EncodingName,
              new EncoderExceptionFallback(), 
              new DecoderExceptionFallback());
        try {
            result=ae.GetString(mybytes);
        }
        catch (DecoderFallbackException e)
        {
            //revert to some sensible default. Maybe the Ansi Code page for this environment?
            // This will use the substitution fallback mechanism, which usually replaces unknown characters with question marks.
            result=Encoding.Default.GetString(mybytes);
        }

Если вы можете взаимодействовать с неуправляемым кодом, изучите MLANG dll, поставляемый с IE. Он имеет альтернативные методы автоопределения кодирования, которые могут быть более полезными.

1 голос
/ 09 июля 2009

Попробуйте это: (Я не проверил, что он соответствует правильно; вы можете легко попробовать это в LINQPad ).

new Regex(@"
    ^(
    [\x09\x0A\x0D\x20-\x7E]            # ASCII
    | [\xC2-\xDF][\x80-\xBF]             # non-overlong 2-byte
    |  \xE0[\xA0-\xBF][\x80-\xBF]        # excluding overlongs
    | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}  # straight 3-byte
    |  \xED[\x80-\x9F][\x80-\xBF]        # excluding surrogates
    |  \xF0[\x90-\xBF][\x80-\xBF]{2}     # planes 1-3
    | [\xF1-\xF3][\x80-\xBF]{3}          # planes 4-15
    |  \xF4[\x80-\x8F][\x80-\xBF]{2}     # plane 16
    )*$", RegexOptions.IgnorePatternWhitespace)

EDIT

Попробуйте прочитать ваш файл, используя ASCII StreamReader; это должно делать то, что вы ищете. (Обратите внимание, что я на самом деле не пробовал это)

1 голос
/ 09 июля 2009

Этот пост на http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/6a81be63-e6da-4156-a5bf-8b9782a1ac40 описывает несколько обходных путей.

0 голосов
/ 09 июля 2009

Что конкретно вы пытаетесь сделать?

Вы можете использовать класс System.Text.Encoding.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...