如何将复杂的二进制Perl正则表达式转换为C#或PowerShell?

时间:2009-07-08 20:14:50

标签: c# regex perl powershell utf-8

http://www.w3.org/International/questions/qa-forms-utf-8.en.php找到的这个Perl二进制正则表达式匹配没有UTF-8 BOM表头的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 equivalent to 'grep -I',其中一部分涉及检测文本编码。

但是如何在C#或PowerShell中重写它?或者换句话说,在“.Net Regex”语法中?

编辑:发现有关所有事情的相同正则表达式的http://social.msdn.microsoft.com/Forums/en-US/regexp/thread/6a81be63-e6da-4156-a5bf-8b9782a1ac40问题。简短的回答似乎无法使用.Net,因为.Net不支持二进制正则表达式。

4 个答案:

答案 0 :(得分: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)

修改

尝试使用ASCII StreamReader读取文件;应该做你想要的。 (请注意,我实际上没有尝试过)

答案 1 :(得分:1)

答案 2 :(得分: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);
        }

如果您可以与非托管代码进行交互,请研究IE附带的MLANG dll。它具有备用编码自动检测方法,可能更有用。

答案 3 :(得分:0)

你具体想做什么?

您应该可以使用System.Text.Encoding类。