对用户输入和文件读取器输入实施编码标准化



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

我猜为了让这两个条目,用户的单词和来自"单词列表"文件的单词匹配编码必须是相同的,这就是我想要修复的。

我从这个网站上取了单词列表。

当我在我的代码中使用来自"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;
    }
}

完整的程序在这里github,它很短,相当明确的注释。

您链接的字典似乎是UTF-16LE格式,而不是UTF-8格式。您应该相应地修复InputStreamReader实例化中的encoding参数。

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要大得多。你不能代表上海市машина

相关内容

  • 没有找到相关文章

最新更新