【问题标题】:Unescape fails when there is regex involved even if the regex is not to be touched即使不触及正则表达式,当涉及正则表达式时,Unescape 也会失败
【发布时间】:2014-08-06 14:59:27
【问题描述】:

我收到一些结果数据如下:

\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+ come here\u003c/div\u003e” - 无法识别的转义序列\w。

我不需要要处理的文本中的正则表达式或任何可以按字面意思理解的内容。

如何转换:

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

恢复正常了吗?

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

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

【问题讨论】:

标签: c# .net-4.5 decode


【解决方案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"));

【讨论】:

  • 不错,您的更新似乎有效,我会尝试一下,看看能否破解它
【解决方案2】:

这里的问题是您尝试将 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+ come here\u003c/div\u003e”作为正则表达式来执行匹配,则无需对其执行任何操作。实现完整正则表达式功能集的匹配器应该理解“\u003c”,因此无需尝试将其转换为“

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

【讨论】:

  • 不,这不是我提到的我的意图,我从某些 API 收到了类似的数据,我想要实现的是将消息恢复到原始状态,然后从中删除 HTML .我很感谢您解释为什么它会失败,但除此之外它相当复杂,而且我无法对它将转换的每个事物标签进行特定替换,因为我不知道将转换什么。
  • 简而言之:您不能在某些时候无法确定与转义/编码配对的东西上使用 unescape/decode。在这种情况下,利用 Unescape 作为工具是很有诱惑力的,但如果源字符串没有以相同的方式转义/编码,它肯定会失败。我没有意识到您无法控制客户端,并假设您打算将其用作正则表达式,因为您使用的是 Regex.Unescape,所以我认为这是字符串形成方式的问题。跨度>
  • @Guapo 要仅针对 unicode 字符,请参阅:stackoverflow.com/questions/183907/…
猜你喜欢
  • 2011-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 2018-04-24
  • 1970-01-01
  • 2016-01-01
相关资源
最近更新 更多