如何在C#中解码%x##格式的RFC 3986编码字符串?
在C#中解码%xXX格式的RFC 3986编码字符串
这个问题我之前也踩过坑!内置的Uri、HttpUtility或WebUtility类只认标准的%XX格式编码,碰到%xXX这种带x前缀的就无法正确解码了。不过有两种简单的解决方案,推荐优先用第一种,省心又靠谱:
方法一:转换格式后用内置解码方法
核心思路是先把非标准的%xXX格式替换成标准的%XX格式,再调用内置方法解码。这里用正则表达式来做替换最方便:
using System.Text.RegularExpressions; // 示例编码字符串 string encodedStr = "Hello%x20World%x21%xE6%x9D%x8E"; // 替换%xXX为%XX string standardEncoded = Regex.Replace(encodedStr, @"%x([0-9A-Fa-f]{2})", "%$1"); // 使用Uri.UnescapeDataString解码(也可以用WebUtility.UrlDecode,注意两者在某些字符上的差异) string decodedStr = Uri.UnescapeDataString(standardEncoded); Console.WriteLine(decodedStr); // 输出: Hello World!李
为什么推荐这种方法?
内置的解码方法已经处理了各种边缘情况,比如UTF-8多字节字符的解码(像上面示例中的中文“李”),不用自己手动处理编码逻辑,避免出错。
方法二:手动实现解码逻辑
如果你不想依赖正则或内置方法,也可以手动遍历字符串处理:
string encodedStr = "Hello%x20World%x21"; List<char> decodedChars = new List<char>(); int index = 0; while (index < encodedStr.Length) { // 检查当前位置是否是%x开头,且后面有足够的字符 if (index + 3 < encodedStr.Length && encodedStr[index] == '%' && encodedStr[index + 1] == 'x') { // 提取后面两位十六进制字符 string hexPart = encodedStr.Substring(index + 2, 2); // 尝试转换为字节 if (byte.TryParse(hexPart, System.Globalization.NumberStyles.HexNumber, null, out byte charByte)) { decodedChars.Add((char)charByte); index += 4; // 跳过%xXX四个字符 continue; } } // 不是有效编码,直接添加原字符 decodedChars.Add(encodedStr[index]); index++; } string decodedStr = new string(decodedChars.ToArray()); Console.WriteLine(decodedStr); // 输出: Hello World!
这种方法适合需要高度自定义解码逻辑的场景,但要注意如果是UTF-8多字节字符,还需要额外处理字节拼接的逻辑,所以一般情况下优先用方法一。
内容的提问来源于stack exchange,提问作者Matteo
相关产品推荐
相关产品推荐

