在C#中将HTML实体转换为Unicode字符

46

我发现了关于Python和Javascript的类似问题和答案,但没有针对C#或其他WinRT兼容语言的内容。

我认为我需要它的原因是因为我正在在Windows 8商店应用程序中显示从网站获取的文本。例如,é 应该变成 é

还有更好的方法吗?我不是显示网站或RSS提要,而只是一个网站列表及其标题。


1
Duplicate: https://dev59.com/wW025IYBdhLWcg3wzpWK - Jelle Vergeer
1
实际上不是这样的。他遇到了另一个问题。 - Remy
确实是重复的。那个问题只是在结尾多了一步,而你并不需要它。 - Michael
6个回答

83

我建议使用System.Net.WebUtility.HtmlDecode而不是HttpUtility.HtmlDecode

这是因为在Winforms/WPF/Console应用程序中不存在System.Web的引用,你可以使用这个类得到完全相同的结果(它已经被添加为所有这些项目的引用)。

用法:

string s =  System.Net.WebUtility.HtmlDecode("é"); // Returns é

4
“你可以使用这个类获得完全相同的结果” - 错误的。只有 HttpUtility 实现能在 WP8 上正确解码 "'" 为撇号。 - Peter Wone
在我的情况下,HttpUtility.HtmlDecode 做了正确的事情。 - Raditya Kurnianto
这是一个不错的解决方案,但缺点是如果你在为旧版Windows 7编写代码,就无法在.NET Framework 3.5下找到System.Net.WebUtility.HtmlDecode。 - Jens Fiederer
链接已损坏。 - liang

12

使用 HttpUtility.HtmlDecode() 方法。在 msdn 上阅读 此处 的文档。

decodedString = HttpUtility.HtmlDecode(myEncodedString)

是的,请注意,对于WinForms或控制台应用程序,您首先必须添加对System.Web程序集的引用。 - Shadow The Spring Wizard
嗨,我尝试了这个解决方案,但它无法解码像{这样的字符 :( - Maria Ines Parnisari
1
@l19是一个被认可的HTML实体吗?我在这个列表中找不到它(http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references)。不过,我在W3C的开发规范中找到了它。这可能就是为什么它还没有被解码的原因。 - crush

11

这可能很有用,将所有(就我需求而言)的实体替换为它们的Unicode等效项。

    public string EntityToUnicode(string html) {
        var replacements = new Dictionary<string, string>();
        var regex = new Regex("(&[a-z]{2,5};)");
        foreach (Match match in regex.Matches(html)) {
            if (!replacements.ContainsKey(match.Value)) { 
                var unicode = HttpUtility.HtmlDecode(match.Value);
                if (unicode.Length == 1) {
                    replacements.Add(match.Value, string.Concat("&#", Convert.ToInt32(unicode[0]), ";"));
                }
            }
        }
        foreach (var replacement in replacements) {
            html = html.Replace(replacement.Key, replacement.Value);
        }
        return html;
    }

1
适用于我的情况,但我编辑了正则表达式为“var regex = new Regex(”(&[a-z]{2,6};)“);”有很多HTML字符长度超过5个字符(例如$eacute;)。 - Marc-André Bilodeau-Lamontagne
我还建议将正则表达式更改为var regex = new Regex("(&[a-zA-Z]{2,7};)");,以便包括诸如&Atilde;之类的字符。 - chrisofspades

3
在Windows Runtime Metro应用程序中,HTML实体和HTML数字的编码方式不同。

在WP8应用中

在WP8应用中,HTML实体和HTML数字的编码方式也有所不同。
{
    string inStr = "ó";
    string auxStr = System.Net.WebUtility.HtmlEncode(inStr);
    // auxStr == &#243;
    string outStr = System.Net.WebUtility.HtmlDecode(auxStr);
    // outStr == ó
    string outStr2 = System.Net.WebUtility.HtmlDecode("&oacute;");
    // outStr2 == ó
}

使用Windows Phone 8.0

{
    string inStr = "ó";
    string auxStr = System.Net.WebUtility.HtmlEncode(inStr);
    // auxStr == &#243;
    string outStr = System.Net.WebUtility.HtmlDecode(auxStr);
    // outStr == &#243;
    string outStr2 = System.Net.WebUtility.HtmlDecode("&oacute;");
    // outStr2 == ó
}

为了解决这个问题,在WP8中,我在调用System.Net.WebUtility.HtmlDecode()之前先使用HTML ISO-8859-1 Reference中的表格进行了实现。

链接已失效。 - Sinatr

2

这对我很有用,可以替换常见和Unicode实体。

private static readonly Regex HtmlEntityRegex = new Regex("&(#)?([a-zA-Z0-9]*);");

public static string HtmlDecode(this string html)
{
    if (html.IsNullOrEmpty()) return html;
    return HtmlEntityRegex.Replace(html, x => x.Groups[1].Value == "#"
        ? ((char)int.Parse(x.Groups[2].Value)).ToString()
        : HttpUtility.HtmlDecode(x.Groups[0].Value));
}

[Test]
[TestCase(null, null)]
[TestCase("", "")]
[TestCase("&#39;fark&#39;", "'fark'")]
[TestCase("&quot;fark&quot;", "\"fark\"")]
public void should_remove_html_entities(string html, string expected)
{
    html.HtmlDecode().ShouldEqual(expected);
}

1

改进的Zumey方法(我无法在那里发表评论)。实体中的最大字符大小为:&exclamation(11)。实体中也可以使用大写字母,例如À(来源于wiki)。

public string EntityToUnicode(string html) {
        var replacements = new Dictionary<string, string>();
        var regex = new Regex("(&[a-zA-Z]{2,11};)");
        foreach (Match match in regex.Matches(html)) {
            if (!replacements.ContainsKey(match.Value)) { 
                var unicode = HttpUtility.HtmlDecode(match.Value);
                if (unicode.Length == 1) {
                    replacements.Add(match.Value, string.Concat("&#", Convert.ToInt32(unicode[0]), ";"));
                }
            }
        }
        foreach (var replacement in replacements) {
            html = html.Replace(replacement.Key, replacement.Value);
        }
        return html;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接