2009-07-08 9 views
3

Diese Perl binäre regex bei http://www.w3.org/International/questions/qa-forms-utf-8.en.php gefunden entspricht UTF-8-Dokumente ohne UTF-8 BOM-Header:Wie kann ich einen komplexen binären regulären Perl-Ausdruck in C# oder PowerShell konvertieren?

$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; 

ich das brauche, weil ich auf einem PowerShell equivalent to 'grep -I' arbeite, und ein Teil davon beinhaltet Textcodierung zu erkennen.

Aber wie schreibe ich das in C# oder PowerShell? Oder mit anderen Worten, in der ".Net Regex" -Syntax?

EDIT: Gefunden http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/6a81be63-e6da-4156-a5bf-8b9782a1ac40 Frage über den gleichen Regex aller Dinge. Die kurze Antwort scheint, dass dies mit .Net nicht möglich ist, da .Net keine binären regulären Ausdrücke unterstützt.

+0

Dies ist eine sehr einfache Regex. Können Sie erklären, welches spezielle Problem Sie haben, um dies zu konvertieren? –

Antwort

0

Was genau versuchen Sie zu tun?

Sie sollten die System.Text.Encoding Klasse verwenden können.

+0

Ich sehe nicht, wie man die Kodierung eines binären Stroms mit dieser Klasse * erkennt. Der reguläre Ausdruck in der Frage entspricht "true", wenn der binäre Stream UTF-8-codiert ist. – kervin

+0

Kervin: Sie können versuchen, den Stream als UTF-8 zu analysieren. Wenn es fehlschlägt, dann war es nicht UTF-8, sonst war es. – Joey

1

Versuchen Sie Folgendes: (Ich habe nicht überprüft, ob es richtig übereinstimmt; Sie können es einfach in LINQPad versuchen).

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:

Versuchen Lesen Sie Ihre Datei mit einem ASCII mit StreamReader; das sollte tun, wonach du suchst. (Beachten Sie, dass ich es nicht wirklich probiert habe)

+0

Der Perl Regex ist ein binärer Regex. Das wird also nicht funktionieren. Nach mehr Forschung scheint es, dass .Net unterstützt binäre reguläre Ausdrücke. – kervin

+0

Sie können den "binären" Regex-Abgleich fälschen, indem Sie den Byte-Stream so decodieren, dass jedes Byte in ein Zeichen mit demselben numerischen Wert konvertiert wird. Verwenden Sie einfach ISO-8859-1. –

1

Die Chancen sind ziemlich gut, dass, wenn eine Sequenz keine ungültigen UTF-8-Zeichen hat, kann es als UTF-8 behandelt werden. Da RegExps für Text in .Net, nicht für Byte-Arrays, gedacht ist, ist hier eine nicht-reguläre Lösung, die funktionieren sollte. Persönlich würde ich dies lieber als Fallback-Mechanismus verwenden (z. B. meinKommando -autodetect) und Pipeline-Parameter anbieten, die benutzerdefinierte Kodierungen erlauben.

Wenn Sie mit nicht verwaltetem Code interagieren können, recherchieren Sie die MLANG-DLL, die mit IE geliefert wird. Es verfügt über alternative Methoden zur automatischen Erkennung, die möglicherweise hilfreicher sind.