gpt4 book ai didi

java - 强制用户输入和文件读取器输入的编码标准化

转载 作者:行者123 更新时间:2023-11-30 08:11:37 25 4
gpt4 key购买 nike

我正在设计一个系统来确定给定文本的人类语言。它的工作原理是为每种感兴趣的语言存储一个字典,然后评估用户输入是否对应于字典存储的任何单词。字典点击次数最多的语言就是获胜者。

我猜想,为了使这两个条目、用户的单词和来自“单词列表”文件的单词匹配,编码必须相同,这就是我正在努力解决的问题。

我从 this site 中获取了单词列表。

当我在代码中使用“ASCII”中的内容时,一切正常,但当我使用“Unicode”中的内容时,一切都不起作用。

这让我感到不安,因为我不希望程序获得一些以错误方式编码的输入(以与我的单词列表数据结构冲突的方式)然后失败。

出于这个原因,我想使用特定的编码来标准化所有输入。我认为“Unicode”会更好,因为这是一个用于确定文本自然语言的系统,我可能会得到一些希腊语、俄语或中文字符,并且根据我的理解“ASCII”是高度非标准化的。

我目前正在使用 Eclipse 的控制台来编写输入。

这就是我读取文件的方式:

//BufferedReader br = new BufferedReader( new InputStreamReader(new FileInputStream( dir.toString() ), "UTF-8") );

BufferedReader br = new BufferedReader( new FileReader( dir.toString() ) );
String line = null;

BloomFilter<String> bloomFilter;
if (word_holding_directory_path.toLowerCase().contains("/de/"))
{
bloomFilter = de_bloomFilter;
}

这是我读取用户输入的方式:

//Scanner in = new Scanner( System.in , "UTF-8");
Scanner in = new Scanner(System.in);

System.out.println("Please enter a sentence: ");

String[] input_text = in.nextLine().split("\\s");

正如您所看到的,我尝试强制编码为 UTF-8(这与 Unicode 是一样的,不是吗?),但由于它不起作用,所以我将其注释掉了。

这就是我比较单词的方式:

for (String word : input_text) 
{
String normalized = word.trim().toLowerCase();
if (words.contains(normalized))
{
++count;
}
}

完整的程序是here on github它很短并且评论相当明确。

最佳答案

您链接到的词典似乎采用 UTF-16LE,而不是 UTF-8。您应该相应地修复 InputStreamReader 实例化中的编码参数。

Unicode 和 UTF-8 显然不是同一件事;事实上,说文本是“Unicode”而不提及编码是不够精确的。1

(您应该能够猜到几年前的 ZIP 文件可能使用 UTF-16LE,这在 Windows 上仍然是许多事情的默认设置。新资源通常是 UTF-8,即使在 Windows 上也是如此。)

从 UTF-16 文件读取一个字符串,并使用正确的控制台编码从控制台读取包含相同文本的另一个字符串,将生成两个相等的 Java 字符串。另一方面,如果其中一个输入流的编码不正确,那么最终在字符串中得到的内容基本上是随机伪造的。 (在“火车失事”场景中,两个输入上都有不同的编码错误,并且恰好得到两个相同的字符串,而实际上这两个字符串应该包含不同的文本。)

(不确定 UTF-8 对于控制台是否普遍正确,或者是否特别适合您的环境 - 我不是 Java 程序员。)

<小时/>

1 简而言之,抽象的 Unicode 字符串

U+0066 U+00F6 U+0072

(代表瑞典语单词för)将表示为

0x66 0xC3 0xB7 0x72

采用 UTF-8(注意纯 ASCII 字符如何映射到身份表示),以及

0x66 0x00 0xF6 0x00 0x72 0x00

采用 UTF-16LE(其中每对字节都是一个 16 位序列,MSB 设置为零,而 LSB 容纳表示的整个重要部分)。

在纯 ASCII 中,无法表示该字符串;回到过去,它会被写成

0x66 0x7C 0x72

其中 0x7C 是正确的管道字符 |,它在本地映射到硬件中的字形 ö。 (相应地,如果您使用的英语资源应该包含适当的管道字符,那么它也会被渲染为 ö;因此 Unix 管道线 grep cat food | xxd 将显示为 grep cat food ö xxd。)

不久之后,ISO-8859-1 开始流行,该字符串将表示为

0x66 0xFC 0x72

这当然是简单而高效的。为什么 Unicode 不也是这样表示的呢?因为8位编码只有256个字符,而Unicode要大得多。你根本不能代表上海市машина

关于java - 强制用户输入和文件读取器输入的编码标准化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30317435/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com