2009-07-08 1 views
3

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

$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 equivalent to 'grep -I', и часть этого включает в себя обнаружение кодировки текста.

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

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

+0

Это очень простое регулярное выражение. Не могли бы вы объяснить, какая конкретная проблема у вас есть? –

ответ

0

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

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

+0

Я не вижу, как * обнаружить * кодировку двоичного потока, используя этот класс. Регулярное выражение в вопросе соответствует true, если двоичный поток кодируется UTF-8. – kervin

+0

kervin: Вы можете попробовать разбор потока как UTF-8. Если это не удается, то это не UTF-8, иначе это было. – Joey

1

Попробуйте следующее: (Я не проверял правильность его соответствия, вы можете легко попробовать его в 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; это должно делать то, что вы ищете. (Заметьте, что я на самом деле не пробовал)

+0

Регулярное регулярное выражение Perl является двоичным регулярным выражением. Так что это не сработает. После дополнительных исследований, похоже, что .Net поддерживает двоичные регулярные выражения. – kervin

+0

Вы можете подделать «двоичное» соответствие регулярному выражению, декодируя поток байтов таким образом, чтобы каждый байт был преобразован в символ с тем же числовым значением. Просто используйте ISO-8859-1. –

1

Коэффициенты довольно хороши, что если последовательность не имеет недопустимых символов 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); 
     } 

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