如何在java中解析单词创建的特殊字符

时间:2010-10-22 19:45:12

标签: java regex parsing

我正在尝试解析java中的一些word文档。有些值是日期范围之类的东西而不是像Startdate那样出现 - endDate我得到了一些像这样的时髦字符

StartDate ΓÇô EndDate

这是单词放入特殊字符的地方。你可以搜索这些字符并用常规字符替换它们 - 或者字符串中的东西,这样我就可以对“ - ”进行标记,那个字符是什么 - ascii? unicode还是什么?

编辑添加一些代码:

 String projDateString = "08/2010 ΓÇô Present"
                Charset charset = Charset.forName("Cp1252");
                CharsetDecoder decoder = charset.newDecoder();
                ByteBuffer buf = ByteBuffer.wrap(projDateString.getBytes("Cp1252"));
                CharBuffer cbuf = decoder.decode(buf); 
                String s = cbuf.toString();
                println ("S: " + s)

                println("projDatestring: " + projDateString)

输出以下内容:

S: 08/2010 ΓÇô Present
projDatestring: 08/2010 ΓÇô Present

另外,如果我这样做,使用相同的projDateString:

projDateString.replaceAll("\u0096", "\u2013");
projDateString.replaceAll("\u0097", "\u2014");

然后打印出projDateString,它仍然打印为

projDatestring: 08/2010 ΓÇô Present

4 个答案:

答案 0 :(得分:6)

你可能正在使用Windows-1252这是一个字符集,而不是编码。 (Torgamus - 用于Windows-1232的谷歌搜索没有给我任何东西。)

Windows-1252,以前的“Cp1252”几乎是 Unicode,但在同一个地方保留了一些来自Cp1252的字符。 En Dash 是字符150(0x96),它属于Unicode C1保留的控制字符范围,不应该在那里。

您可以搜索char 150并将其替换为\u2013,这是En Dash的正确Unicode代码点。

MS在0x80到0x9f范围内有很多其他字符,这是Unicode标准中保留的,包括Em Dash,项目符号及其“智能”引号。


编辑:顺便说一下,Java在内部使用字符的Unicode代码点值。 UTF-8是编码,在将字符串写入文件或网络连接时,Java将其用作默认编码。


说你有

String stuff = MSWordUtil.getNextChunkOfText();

MSWordUtil将会以某种方式编写某些MS-Word .doc文件。它可能归结为

File myDocFile = new File(pathAndFileFromUser);
InputStream input = new FileInputStream(myDocFile);
// and then start reading chunks of the file

默认情况下,当您从文件中读取字节缓冲区并从中生成字符串时,Java会将其视为UTF-8编码文本。正如Torgamus勋爵所说,有很多方法可以告诉应该使用什么编码,但没有这样做,Windows-1252非常接近UTF-8,除了C1中有那些讨厌的字符控制范围。

在获得上面的stuff之类的字符串之后,您将找不到\u2013\u2014,而是找到0x96和0x97。

此时你应该能够做到

stuff.replaceAll("\u0096", "\u2013");

我不会在我的代码中那样做,我必须处理这个问题。我一次循环输入CharSequence一个字符,根据0x80 <= charValue <= 0x9f决定是否必须替换它,并在数组中查找要替换它的内容。如果你关心的是1252 En Dash和Unicode En Dash,那么上面的replaceAll()会容易得多。

答案 1 :(得分:4)

s = s.replace( (char)145, (char)'\'');

s = s.replace( (char)8216, (char)'\''); // left single quote

s = s.replace( (char)146, (char)'\'');

s = s.replace( (char)8217, (char)'\''); // right single quote

s = s.replace( (char)147, (char)'\"');

s = s.replace( (char)148, (char)'\"');

s = s.replace( (char)8220, (char)'\"'); // left double

s = s.replace( (char)8221, (char)'\"'); // right double

s = s.replace( (char)8211, (char)'-' ); // em dash??    

s = s.replace( (char)150, (char)'-' );

http://www.coderanch.com/how-to/java/WeirdWordCharacters

答案 2 :(得分:2)

您的问题几乎肯定与您的编码方案不符合Word保存的编码方案有关。您的代码可能使用Java默认值,如果您没有对其进行任何操作,则可能UTF-8。另一方面,您的输入可能是Windows-1252,这是Microsoft Word .doc文档的默认设置。有关详细信息,请参阅this site。值得注意的是,

  

在Windows中,ISO-8859-1被Windows-1252取代,这通常意味着从Microsoft Word文档复制并直接粘贴到网页中的文本会产生HTML验证错误。

那么这对你意味着什么?您必须告诉您的程序输入使用的是Windows-1252编码,并将其转换为UTF-8。你可以用不同的“手动”方式做到这一点。可能最自然的方式是利用Java的内置Charset class

the IANA Charset Registry

识别Windows-1252
  

名称:windows-1252
  MIBenum:2252
  资料来源:微软(http://www.iana.org/assignments/charset-reg/windows-1252)[Wendt]
  别名:无

所以你应该Charset - 兼容。我之前没有这样做过,所以我不能给你一个代码示例,但我会指出有一个String构造函数需要byte[]Charset作为论点。

答案 3 :(得分:1)

可能这个角色是en dash,你看到的奇怪的模糊是由于Word编码该角色的方式与你使用的任何(其他)系统解码角色的方式不同显示它。

如果我在Java中对字符编码做了一些工作时没有记错,String个实例总是在内部使用UTF-8;因此,在这样的实例中,您可以通过Unicode表单搜索和替换单个字符。例如,假设你想用简单的双引号替换智能引号:给定String s,你可以写

s = s.replace('\u201c', '"');
s = s.replace('\u201d', '"');

其中201c201d是打开和关闭智能引号的Unicode代码点。根据Wikipedia上面的链接,en dash的Unicode代码点是2013