如何使用URL编码将带有URL的Unicode文本文件转换为ANSI

时间:2015-04-14 19:08:12

标签: c# unicode urlencode

我有一些包含网址的大型文本文件。它们以UCS-2 Little Endian编码。它们包含各种链接,包括:阿拉伯语,中文,日语,韩语,俄语以及您在其URL中可以想到的所有语言。

我的目标是创建一个脚本,自动对所有这些链接进行URL编码,并将它们保存在ANSI编码文件中。

示例:

以下是一些原始链接:

http://ejje.weblio.jp/content/あきれて物が言えない
https://ru.wikipedia.org/wiki/Дактиль
http://zh.wikipedia.org/zh/垃圾食品
http://abunawaf.com/سيارات-الملوك-وورثتهم-صور
http://ko.wiktionary.org/wiki/가능해지다

这些需要成为:

http://ejje.weblio.jp/content/%e3%81%82%e3%81%8d%e3%82%8c%e3%81%a6%e7%89%a9%e3%81%8c%e8%a8%80%e3%81%88%e3%81%aa%e3%81%84
https://ru.wikipedia.org/wiki/%d0%94%d0%b0%d0%ba%d1%82%d0%b8%d0%bb%d1%8c
http://zh.wikipedia.org/zh/%e5%9e%83%e5%9c%be%e9%a3%9f%e5%93%81
http://abunawaf.com/%d8%b3%d9%8a%d8%a7%d8%b1%d8%a7%d8%aa-%d8%a7%d9%84%d9%85%d9%84%d9%88%d9%83-%d9%88%d9%88%d8%b1%d8%ab%d8%aa%d9%87%d9%85-%d8%b5%d9%88%d8%b1
http://ko.wiktionary.org/wiki/%ea%b0%80%eb%8a%a5%ed%95%b4%ec%a7%80%eb%8b%a4

我用C#来做到这一点。我尝试过像这样使用HttpUtility.UrlPathEncode方法:

    static void Main(string[] args)
    {

        string path = @"c:\temp\test.txt";
        string enpath = @"c:\temp\entest.txt";

        string[] lines = File.ReadAllLines(path);

        for (int i = 0; i < 72; i++)
        {
            Console.Write(HttpUtility.UrlPathEncode(lines[i]) + Environment.NewLine);
            System.IO.File.AppendAllText(enpath, HttpUtility.UrlPathEncode(lines[i]) + Environment.NewLine, Encoding.ASCII);
        }

        Console.ReadLine();

    }

除了一个小错误之外,它似乎正在很好地转换它们:如果URL包含问号,则它不会转换后的任何内容。这对我来说是一个很大的障碍,因为我有很多包含问号的链接。

示例:

http://www.alkousy.com/showthread.php?4113-ÇáÚáã-ÈÇááøóå-åæ-ßäÒ-ÇáÃäÈíÇÁ-ææÑËÊåã-ãä-ÇáãÄãäíä

正在转换为:

http://www.alkousy.com/showthread.php?4113-?????-???????-??-???-????????-???????-??-????????

这对我来说是完全不能接受的,我正在寻找另一种解决方案。我也尝试过Uri.EscapeDataString,但是这个人会转换包括//和:

在内的所有东西

有没有自定义编码的快速解决方案?

1 个答案:

答案 0 :(得分:0)

改为使用Uri类:

var url = "http://www.alkousy.com/あきれて物が言.php?4113-ÇáÚáã-ÈÇááøóå-åæ-ßäÒ-ÇáÃäÈíÇ";
var uri = new Uri(url, UriKind.Absolute);
Console.WriteLine(uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped));

将输出:

http://www.alkousy.com/%E3%81%82%E3%81%8D%E3%82%8C%E3%81%A6%E7%89%A9%E3%81%8C%E8
%A8%80.php?4113-%C3%87%C3%A1%C3%9A%C3%A1%C3%A3-%C3%88%C3%87%C3%A1%C3%A1%C3%B8%C3
%B3%C3%A5-%C3%A5%C3%A6-%C3%9F%C3%A4%C3%92-%C3%87%C3%A1%C3%83%C3%A4%C3%88%C3%AD%C
3%87

Uri类理解URI是一个实际的URI,因此它知道不对协议进行编码。因此,我们可以将您的代码调整为:

static void Main(string[] args)
{

    string path = @"c:\temp\test.txt";
    string enpath = @"c:\temp\entest.txt";

    string[] lines = File.ReadAllLines(path);

    for (int i = 0; i < 72; i++)
    {
        var uri = new Uri(lines[i], UriKind.Absolute);
        var escaped = uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
        Console.WriteLine(escaped);
        System.IO.File.AppendAllText(enpath, escaped + Environment.NewLine, Encoding.ASCII);
    }

    Console.ReadLine();
}

根据评论,我们可以将其实现为foreach循环:

foreach (var line in lines)
{
    Uri uri;
    if (Uri.TryCreate(line, UriKind.Absolute, out uri))
    {
        var escaped = uri.GetComponents(UriComponents.AbsoluteUri, UriFormat.UriEscaped);
        Console.WriteLine(escaped);
        System.IO.File.AppendAllText(enpath, escaped + Environment.NewLine, Encoding.ASCII);
    }
}