将不同字符集的纯文本转义为RTF格式

时间:2016-04-21 10:35:57

标签: c# character-encoding escaping rtf utf

我想解析任何文本并将其编码为RTF格式,我找到了一个简单的解决方案,只是为了将文本放在一些"基本模板"。

这可以正常工作,直到文字不包含任何特殊字符。

我需要能够逃脱日语,中文,俄语,拉丁语等特殊字符等。

例如,这个:

  

追伸。次回の発表が気になる场合は,こちらをご确认ください。

应该转义为:

  

\' 92 \' C7 \' 90 \'图4c \' 81 \' 42 \' 8E \' 9F \' 89 \' F1 \' 82 \' CC \' 94 \'广告\' 95 \'图5c \ ' 82 \' AA \'图8b \' 43 \' 82 \' C9 \' 82 \' C8 \&# 39; 82 \' E9 \' 8F \' EA \'图8d \' 87 \' 82 \' CD \' 81 \' 41 \' 82 \' B1 \' 82 \' BF \' 82 \' E7 \' 82 \ ' F0 \' 82 \' B2 \'图8a \'图6d \' 94 \' 46 \' 82 \&# 39;广告\' 82 \'是\' 82 \' B3 \' 82 \' A2 \' 81 \' 42 \

是否有可以处理此问题的C#库,或者有任何简单的解决方案如何实现这一目标?

3 个答案:

答案 0 :(得分:1)

王永涛的C#版答案:

public static string Escape(string s)
{
    if (s == null) return s;

    var sb = new StringBuilder();
    foreach (char c in s)
    {
        if (c >= 0x20 && c < 0x80)
        {
            if (c == '\\' || c == '{' || c == '}')
            {
                sb.Append('\\');
            }
            sb.Append(c);
        }
        else if (c < 0x20 || (c >= 0x80 && c <= 0xFF))
        {
            sb.Append($"\\'{((byte)c).ToString("X")}");
        }
        else
        {
            sb.Append($"\\u{(short)c}?");
        }
    }
    return sb.ToString();
}

如果字符串可以包含换行符,则还需要在返回转义字符串之前调用此方法:

private static string FixLineBreaks(string str)
{
     return str.Replace(@"\'d\'a", @"\line ");
}

答案 1 :(得分:0)

你需要处理不容易的不同字符集。

首先,您需要将charcter编码转换为您需要的语言,例如GB2312 for Chinese,然后将char值转换为十六进制字符串。

最简单的方法是将它们转换为unicode,而现在的RTF读者支持它:

以下是Java中的一些代码,应该很容易将其转换为C#     public static String escape(String s){             if(s == null)返回s;

        int len = s.length();
        StringBuilder sb = new StringBuilder(len);
        for (int i = 0; i < len; i++){
            char c = s.charAt(i);
            if (c >= 0x20 && c < 0x80){
                if (c == '\\' || c == '{' || c == '}'){
                    sb.append('\\');
                }
                sb.append(c);
            }
            else if (c < 0x20 || (c >= 0x80 && c <= 0xFF)){
                sb.append("\'");
                sb.append(Integer.toHexString(c));
            }else{
                sb.append("\\u");
                sb.append((short)c);
                sb.append("??");//two bytes ignored
            }
        }
        return sb.toString();
    }

答案 2 :(得分:0)

感谢您的帮助!

我正在查看此线程是因为我需要Rtf Escape来将信息传递给Wordpad或任何Rtf控件,并修改了C#版本的代码,只是对一些大于32767的char值进行了强制转换还不够。

另外,我需要强制使用2个十六进制数字(在0x00-0x20和0x80-0xFF之间的字符)(这就是为什么我需要使用ToString(“ X2”)):

public static string Escape(string source)
{
    if (string.IsNullOrEmpty(source)) return string.Empty;

    var sb = new StringBuilder();
    foreach (char c in source)
    {
        if (c >= 0x20 && c < 0x80)
        {
            if (c == '\\' || c == '{' || c == '}')
            {
                sb.Append('\\');
            }
            sb.Append(c);
        }
        else if (c < 0x20 || (c >= 0x80 && c <= 0xFF))
        {
            sb.Append($"\\'{((byte)c).ToString("X2")}");
        }
        else
        {
            sb.Append($"\\u{(int)c}?");
        }
    }
    return sb.ToString();
}

希望这会有所帮助!