清理unicode字符串以进行日志记录

时间:2019-11-25 11:21:36

标签: c# regex unicode-string

我正在写一个字符串清洗器,然后使用以下规则将数据写入日志文件:

  1. 指定的字符被列入白名单(<div class="col-sm-4"> <div class="ldBar auto no-percent label-center m-auto" id="tree" style="height: 300px; width: 300px;" >>>>>>data-value="50"<<<<<< data-type="fill" data-img="tree1.svg" data-fill="data:ldbar/res,bubble(#f00,#d00,100,1)" data-fill-background="#ddd" data-fill-background-extrude="0"> <svg xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid" width="100%" height="100%" viewBox="-4.5 -4.5 109 109"> </svg> <div class="ldBar-label"></div> </div> </div> 以及A-Za-z0-9和空格)
  2. 将指定字符转换成英文名称的英文括弧(例如<>[],.:_-"," => "<comma>"
  3. 其他任何内容都将转换为其在方括号内的unicode号(例如"%" => "<percent>""φ" => "<U+03C6>"

到目前为止,第1个和第2个正在工作,但第3个却没有。这是我到目前为止的工作:

"π" => "<U+03C0>"

正则表达式部分未在输入字符串中捕获unicode字符。我该如何解决

1 个答案:

答案 0 :(得分:0)

问题是,我假设将字符串转换为string数组(char时,C#char[]中存在的单个unicode值将转换为多个项目。 )。如果您将鼠标悬停在Visual Studio中的stringchar类型上,那么它实际上会告诉您这两种类型与unicode有何关系:

  • string:将文本表示为一系列Unicode字符
  • char:将字符表示为UTF-16代码单元

这意味着C#字符串中的每个“字母”(即字符)实际上都是unicode char,因此,当您将字符串转换为char数组时,该字符串的每个项目数组现在包含1个Unicode字符。

还有另外一个谜题:我们如何知道Regex.Match()一次操作一个Unicode字符?它使用UTF-16还是UTF-32?对于这个问题的答案,我looked up the documentation

  

\u nnnn-使用十六进制表示形式(以nnnn表示的四位数字)匹配Unicode字符。

因此C#正则表达式支持UTF-16(2个字节),但不支持UTF-32。像.{1}这样的模式将精确捕获1个UTF-16字符。

因此,解决方案就是根本不尝试从原始问题的itemMatch.ToString().ToCharArray()中取出2个项目-因为那里只有1个项目!这是规则3(我受困的部分)缺少的解决方案:

        Regex itemRegex = new Regex(@"[^A-Za-z0-9<>[\]:\.,_\s-]", RegexOptions.Compiled); // {1} is implied

        foreach (Match itemMatch in itemRegex.Matches(s))
        {
            char unicodeChar = itemMatch.ToString().ToCharArray()[0]; // 1 char = 16 bits
            int unicodeNumber = (int)unicodeChar;
            string unicodeHex = unicodeNumber.ToString("X4");
            s = s.Replace(itemMatch.ToString(), "<U+" + unicodeHex + ">");
        }
        return s;