即使不接触正则表达式,当涉及正则表达式时,Unescape也会失败

时间:2014-08-06 14:59:27

标签: c# .net-4.5 decode

我收到的结果数据如下:

\u003cdiv\u003esome message comes here\u003c/div\u003e

我需要解析它,这很容易完成:

string result = HttpUtility.HtmlDecode(Regex.Unescape(data));

但是,如果字符串中有正则表达式,例如:

\u003cdiv\u003esome message \w+ comes here\u003c/div\u003e

会抛出错误:

  

解析“\ u003cdiv \ u003esome message \ w +来到这里\ u003c / div \ u003e” - 无法识别的转义序列\ w。

我不需要要处理的文本中的正则表达式或者实际上可以采用字面意思的任何内容。

我该如何转换:

\u003cdiv\u003esome message \w+ comes here\u003c/div\u003e

恢复正常?

<div>some message \w+ comes here</div>

注意:我环顾四周但没有找到针对此的答案,我确实找到了答案,告诉人们使用@然而数据不是由我输入的,而是从其他地方收到的,所以我不认为我可以做string data = @receivedData; AFAIK。

2 个答案:

答案 0 :(得分:1)

这里混合了两种不同的转义类型。你可以试试这个:

Regex.Unescape(Regex.Replace(data, "\\\\([^u])", "\\\\$1"))

这将保留\u...值但转义其他反斜杠。

如果您经常执行此操作,您将要创建Regex模式实例并在每次调用时重复使用它:

Regex regex = new Regex("\\\\([^u])"); // Reuse this instance

// When parsing the data:
Regex.Unescape(regex.Replace(data, "\\\\$1"));

答案 1 :(得分:1)

这里的问题是你试图将Regex.Unescape应用于未完全用Regex.Escape处理的东西。几乎任何编码都会遇到同样的问题,其中您有一个部分编码的消息和其他未编码的部分。您可以尝试预测所有变体,但是在某些情况下,您将无法区分未编码的内容和其他未转义的内容。唯一可靠的解决方法是确保整个消息的编码一致。这意味着,只要您对字符串执行操作,然后重新编码整个字符串,就会完全解码消息。

以下是我在linqpad中执行的演示,其中输出将跟随每个对应的.Dump()。它执行完整编码,然后完成解码。你会注意到在正则表达式编码时,\ w中途会被转义。 所以问题的症结在于消息中的“某些消​​息\ w + here”部分不是正则表达式编码,因此将Regex.Unescape应用于它将会失败,因为你无法忽略它的某些东西。没有逃脱。

string ori = @"<div>some message \w+ here</div>"; //only escaping is \\ for the C# string which is really \

ori.Dump(); // Verify that real string is "<div>some message \w+ here</div>"

string regexEscaped = System.Text.RegularExpressions.Regex.Escape(ori);

regexEscaped.Dump();    

//Regex escape does not replace "<" with unicode characters as it seems an unnecesary escape sequence.  I can force them into the regex encoded string
//This step is unnecesary and can be commented out.
//regexEscaped = regexEscaped.Replace(">", @"\u003e").Replace("<",@"\u003c");    
//regexEscaped.Dump();

string htmlEscaped_regexEscaped = System.Web.HttpUtility.HtmlEncode(regexEscaped).Dump();

System.Text.RegularExpressions.Regex.Unescape( System.Web.HttpUtility.HtmlDecode(htmlEscaped_regexEscaped)).Dump();
// Since we encoded the entire string we were able to successfully decode it.

输出:

 Original: <div>some message \w+ here</div>
Rgx Escpd: <div>some\ message\ \\w\+\ here</div>
HTML Encd: &lt;div&gt;some\ message\ \\w\+\ here&lt;/div&gt;
HTML Uncd & Rgx Unesc: <div>some message \w+ here</div>

您是否正在使用它进行匹配?

如果您打算使用字符串“\ u003cdiv \ u003esome message \ w +来这里\ u003c / div \ u003e”作为执行匹配的Regex表达式,则无需对其执行任何操作。实现完整正则表达式功能集的匹配器应该理解“\ u003c”,因此无需尝试将其转换为“&lt;”:

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

客户端真的不是在做Regex Escape吗?

客户端似乎不太可能正在进行正则表达式转义,因此Regex.Unescape肯定会失败。它是在做某种Html编码,但用unicode代码而不是HTML字符代码替换字符?也许。如果客户没有记录在案的行为,那么这是一种有根据的猜测,希望他们不会在以后产生其他不一致的编码。

在这种情况下,我只会定位unicode转义序列。这是一个问题,涵盖了替换unicode转义序列和不使用Regex.Unescape 的主题:

How do convert unicode escape sequences to unicode characters in a .NET string