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

How to Convert Unicode Text File With URLs to ANSI using URL Encoding

我有一些包含 URLs 的大型文本文件。它们以 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,但是这个人转换了所有内容,包括 // 和 :

是否有无需自定义编码的快速解决方案?

改用Uri class:

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 class 理解 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);
    }
}