2010-10-22 68 views
2

我想解析java中的一些word文檔。一些值是事情,比如日期範圍,而不是顯示像開始日期了 - 結束日期我得到一些時髦的人物,像這樣如何解析java中創建的特殊字符

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"); 

,然後打印out projDateString,它仍然打印爲

projDatestring: 08/2010 ΓÇô Present 
+0

我如何短語質疑正確呢?我正在尋找一種方法檢測連字符是否在 – Derek 2010-10-22 19:53:09

+0

哦,我明白你的意思。我將編輯我的帖子。 – Pops 2010-10-22 19:56:00

+0

你得到的可能是* En Dash *或者可能是* Em Dash * – 2010-10-22 20:13:03

回答

6

您可能正在獲取Windows-1252,它是一個字符集,而不是編碼。 (Torgamus - 谷歌搜索的Windows-1232並沒有給我任何東西)

的Windows 1252,原名「的Cp1252」是幾乎統一,但會保留來自於的Cp1252他們的同一個地方的某些字符。 En Dash是字符150(0x96),它落在Unicode C1保留的控制字符範圍內,不應該在那裏。

您可以搜索字符150並替換爲\u2013,這是適合En Dash的Unicode代碼點。

MS在0x80到0x9f範圍內還有其他一些字符,這些字符在Unicode標準中保留,包括Em Dash,項目符號和它們的「智能」引號。


編輯:順便說一下,Java在內部使用Unicode碼位值作爲字符。 UTF-8是編碼,在將Strings寫入文件或網絡連接時,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勳爵所說,有很多方法可以用於告訴應該使用什麼編碼,但除非有那些討厭的字符在C1控制範圍內,否則Windows-1252與UTF-8非常接近。

上面得到一些像stuff這樣的字符串後,你不會在其中找到\u2013\u2014,你會發現0x96和0x97。

在這一點上,你應該能夠做到

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

我不這樣做,在我的代碼在那裏我不得不處理這個問題。我一次循環輸入一個字符CharSequence,根據0x80 <= charValue <= 0x9f決定是否必須替換它,然後在數組中查找要替換的字符。上面的replaceAll()更容易,如果你關心的是1252 En Dash vs.Unicode En Dash。

+0

+1 0x80 - 0x9f'信息 – Pops 2010-10-22 20:39:14

+0

因此,我的傳入字符串是從Cp1252出來的,它是從Cp1252出來的,對吧?如果我打算將En Dash從中剝離出來,那我該怎麼做?認爲它可能是像String newString = new String(oldString.getBytes(「CP1252),」UTF-8「),但似乎沒有工作 - newString仍然打印有趣的字符,我搜索\ u2013和\ u2014 – Derek 2010-10-22 22:07:59

+1

給定一個'File input'對象,從磁盤上Word文檔的名字創建,你可以嘗試'char [] chars = new char [(int)(input.length())]; Reader in = new InputStreamReader(new FileInputStream(input),encoding); in.read(chars); in.close(); String s = new String(chars);''encoding'應該是您的Word文件的字符編碼。那麼''s'應該在內部使用UTF-8,所以你可以輕鬆搜索'\ u2013'或其他任何東西 – 2010-10-22 22:36:59

2

你的問題幾乎肯定與你的編碼方案有關,而不是與Word保存的編碼方案相匹配。你的代碼可能使用了Java默認值,如果你沒有做任何事情,可能是使用了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

的Windows 1252被the IANA Charset Registry

名稱確認:窗口1252
MIBenum:2252
來源:Microsoft(http://www.iana.org/assignments/charset-reg/windows -1252)[溫特]
別名:無

,所以你應該Charset兼容。我之前沒有做過這件事,所以我不能給你一個代碼示例,但我會指出,有一個String構造函數需要一個byte[]和一個Charset作爲參數。

+0

ASCII和Unicode是*字符集*,而不是編碼。當你從一個字符集中獲得一個特定的字符值時,你必須決定如何將該值寫入磁盤。 *這是*編碼是什麼。 – 2010-10-22 20:30:50

+0

@Stephen,嗯,我已經學到了一些[關於語義](http://en.wikipedia.org/wiki/Character_set#General_terminology)。看起來,我們兩個人都不完全正確。 – Pops 2010-10-22 20:35:40

+0

真的很喜歡你的編輯! – 2010-10-22 20:47:07

1

可能是那個角色是en dash,你看到的奇怪聲音是由於Word對該字符進行編碼的方式與用來顯示它的任何(其他)系統對字符進行解碼的方式之間的區別所致。

如果我沒有記錯,當我在Java中對字符編碼做了一些工作時,String實例始終在內部使用UTF-8;因此,在這種情況下,您可以按Unicode格式搜索和替換單個字符。例如,假設你想用普通雙引號替換智能引號:給定一個String s,你可能會寫

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

其中201c201d是用於打開和關閉智能引號的Unicode代碼點。根據維基百科上面的鏈接,en短劃線的Unicode代碼點爲2013

+0

如果Word自動替換用戶自己的角色, d懷疑在短跑之前他們會衝刺。 – Pops 2010-10-22 20:38:32

+0

在回答之前,我在Word文檔中做了一個簡單的測試:在我的屏幕上,角色似乎是一個短劃線,但你可能是對的。 – 2010-10-22 22:24:48

+0

在Word中,如果您鍵入'2010 - Present',則會用單個*短劃線* – 2010-10-23 00:02:25

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