【问题标题】:RegEx to remove all control / invisible characters EXCEPT CR or LFRegEx 删除所有控制/不可见字符,除了 CR 或 LF
【发布时间】:2015-02-05 19:51:16
【问题描述】:

我正在尝试使用正则表达式 (.Net) 来“清理”Unicode 输入字符串——要求是删除所有不可见字符/控制字符,除了 CR(回车)和 LF(换行符)。换句话说,保留所有有效的可打印字符(英语和法语),包括 CR 和 LF。

我已经尝试了以下(只是使用下划线来查看被替换的内容),但它也删除了 CR / LF ...

clean_str = Regex.Replace( in_str, "\p{C}+", "_" )

也试过了:

clean_str = Regex.Replace( in_str, "(\p{Cf}|\p{Co}|\p{Cs}|\p{Cn}|[\x00-\x09]|\x0b|\x0c|[\x0e-\x1f]|\x7f)+", "_" )

来自http://www.regular-expressions.info/unicode.html ...

p{C} or \p{Other}: invisible control characters and unused code points.

 ◦\p{Cc} or \p{Control}: an ASCII 0x00–0x1F or Latin-1 0x80–0x9F control character.
 ◦\p{Cf} or \p{Format}: invisible formatting indicator.
 ◦\p{Co} or \p{Private_Use}: any code point reserved for private use.
 ◦\p{Cs} or \p{Surrogate}: one half of a surrogate pair in UTF-16 encoding.
 ◦\p{Cn} or \p{Unassigned}: any code point to which no character has been assigned.

大师 - 如果您有更好/更有效的方法 - 请发布!

提前致谢!

【问题讨论】:

    标签: .net regex unicode


    【解决方案1】:

    您可以使用字符类减法从控制字符类中排除 CR 和 LF:

    clean_str = Regex.Replace( in_str, "[\p{C}-[\r\n]]+", "" )
    

    【讨论】:

    • 抱歉 -- 不适用于包含括号或其他特殊可打印字符的字符串 -- 即:[ ] ..
    • 是的——也可以——谢谢!想知道哪个会更快 - Regex.Replace() 或遍历字符串?
    • 这是一个很好的问题,虽然我怀疑正则表达式代码会更快,但我认为唯一确定的方法是在不同长度的字符串上对它们进行基准测试。
    • 正确 - 但为了运行有效的测试 - 我需要知道 {C} 字符类是由什么组成的(以便构建等效的 case 语句)。在 Microsoft 文档中找不到任何内容:msdn.microsoft.com/en-us/library/az24scfc(v=vs.110).aspxmsdn.microsoft.com/en-us/library/… - 所以目前我正在使用正则表达式。
    • fileformat.info/info/unicode/category/index.htm 浏览它,Cx 组中似乎有很多字符
    【解决方案2】:

    作为使用RegEx 的替代方法,您可以只迭代字符串:

    public string Clean(string dirty)
    {
        var clean = new StringBuilder();
     
        const char SPACE = ' ';
        const char LF = '\n';
        const char CR = '\r';
        const char DEL = (char)127;
    
        foreach (var c in dirty)
        {
            switch (c)
            {
                case CR or LF:
                    clean.Append(c);
                    break;
    
                case <= SPACE or DEL:
                    continue;
    
                default:
                    clean.Append(c);
                    break;
            }
        }
    
        return clean.ToString();
    }
    

    【讨论】:

    • 可能是最简单的——但是 ASCII 127 (DEL) 怎么样——这样的代码是不可打印的?我知道——将代码添加到 case 语句中...
    • 我已经用工作 C# 替换了伪代码,@bdcoder。它考虑了DEL
    猜你喜欢
    • 2012-03-22
    • 1970-01-01
    • 2011-09-12
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多