2011-01-26 16 views
16

私はJavaプログラムのテキストファイルをいくつか読み、ASCII近似でいくつかのUnicode文字を置き換えたいと思っています。これらのファイルは最終的にOpenNLPに送られる文章に分割されます。 OpenNLPはUnicode文字を認識せず、多くのシンボル( "girl"と "s"をトークン化しますが、Unicode引用符の場合は単一トークンとして扱います)に不適切な結果を与えます。ユニコード句読点をASCII近似に置き換える

例えば、ソース文章にはUnicode方向引用符U2018( ')を含めることができ、それをU0027(')に変換したいと考えています。最終的に残りのUnicodeを削除します。

私は情報が失われていることを理解しています。これらのシンボルをそれぞれ変換する正規表現を書くことができますが、これらのシンボルの一部を変換するために再利用できるコードがあるかどうかを尋ねています。

これは何私ができるですが、私は、私は:など/

// double quotation (") 
    replacements.add(new Replacement(Pattern.compile("[\u201c\u201d\u201e\u201f\u275d\u275e]"), "\"")); 

    // single quotation (') 
    replacements.add(new Replacement(Pattern.compile("[\u2018\u2019\u201a\u201b\u275b\u275c]"), "'")); 

代替品である私は、後に轢かや交換を適用するカスタムクラスをミス/ミスのものを作ると確信しています。

for (Replacement replacement : replacements) { 
     text = replacement.pattern.matcher(text).replaceAll(r.replacement); 
    } 

あなたが見ることができるように、私が見つけなければならなかった:

  • LEFT SINGLE QUOTATION MARK
  • RIGHT SINGLE QUOTATION MARK
  • SINGLE LOW-9引用符(これは何か/ Iがすべきこれを置き換えてください)
  • 1つのハイリバーシブ9クォートマーク(これは何ですか/これを置き換える必要がありますか)
+0

特定の言語のライブラリやサンプルコードをお探しですか?または、ASCII近似にUnicode文字の既存のマッピングを探していますか?私はあなたが再利用できる正規表現とコードの間に何があるか分かりません。 –

+0

私はJavaライブラリを探しています。私は正規表現を書くことができますが、私はその過程で何かが恋しくなることを確信しています。他の誰かがすでに私のために決定を下したのかどうか疑問に思っていました。 GEB、Mu Mindを読んでいますか? – schmmd

+0

これらのユニコードリンクが死んでいる – user833970

答えて

5

各ユニコード文字にはcategoryが割り当てられます。二つの別々のカテゴリの引用符のため が存在する。これらのリストでは

は、あなたが手動で正規表現をコーディングしたい場合は、適切にすべての引用符を処理することができるはずです。

Java Character.getTypeには、文字のカテゴリがあります(例:FINAL_QUOTE_PUNCTUATION)。

各句読点のカテゴリを取得し、ASCIIで適切な補足と置き換えることができます。

それに応じて、他の句読点カテゴリを使用することができます。 'Punctuation, Other'には、PRIME などの文字があり、アポストロフィで置き換えることもできます。

+0

基本文字に割り当てられたUnicodeカテゴリが不十分なように見えるので、私は定義できるだけ多くの文字でカスタムマップを使用しています。たとえば、基本的な一重引用符文字(キーボードを使用してメモ帳に入力するもの)は、それらのカテゴリに分類されると思われる句読点の初期および句読点の最終カテゴリではなく、「句読点その他」に分類されます。 – Triynko

+0

@Triynko - 問題があります:「普通」(ASCII)の一重引用符と二重引用符が1つしかないため、「INITIAL」または「FINAL」の引用符としてマークすることも間違っています。 –

3

あなたの質問に正確には答えられませんが、UnicodeテキストをUS-ASCIIに変換して、非ASCII文字を '?'シンボル。私は同様の置換のために何をやったか

String input = "aáeéiíoóuú"; // 10 chars. 

Charset ch = Charset.forName("US-ASCII"); 
CharsetEncoder enc = ch.newEncoder(); 
enc.onUnmappableCharacter(CodingErrorAction.REPLACE); 
enc.replaceWith(new byte[]{'?'}); 

ByteBuffer out = null; 

try { 
    out = enc.encode(CharBuffer.wrap(input)); 
} catch (CharacterCodingException e) { 
    /* ignored, shouldn't happen */ 
} 

String outStr = ch.decode(out).toString(); 

// Prints "a?e?i?o?u?" 
System.out.println(outStr); 
+1

Normalizer.normalize(text、Normalizer.Form.NFD)で区切り記号を削除した後、Pattern.compile( "\\ p {InCombiningDiacriticalMarks} +")で置き換えます。 – schmmd

+0

この解決策では、マッピングされるべき引用符のような基本的な句読点は、ASCII引用符にマッピングされません。 "これは基本的にこのASCII文字と同じものです"と言う他の多くのUnicode文字は正しくマップされません。したがって、すべての合理的な置き換えでカスタムマップを使用すると、より良い結果が得られると思います。 – Triynko

2

Map(通常HashMap)キーと値としての代替としてUnicode文字とを作成することです。

擬似Java; forは、これを行うメソッドのパラメータとして使用している文字コンテナの種類によって異なります。文字列、CharSequenceなど

マップ内のものはすべて置き換えられ、マップにないものは変更されずに出力にコピーされます。

6

私は、@マレク・stojのリンクをたどっし、文字列の長さを維持しながら、文字列のうち、ユニコードをきれいにScalaのアプリケーションを作成しました。それは発音区別記号(アクセント)を削除し、@ marek-stojによって提案されたマップを使用して、非ASCII Unicode文字をASCII近似に変換します。

import java.text.Normalizer 

object Asciifier { 
    def apply(string: String) = { 
    var cleaned = string 
     for ((unicode, ascii) <- substitutions) { 
     cleaned = cleaned.replaceAll(unicode, ascii) 
     } 

    // convert diacritics to a two-character form (NFD) 
    // http://docs.oracle.com/javase/tutorial/i18n/text/normalizerapi.html 
    cleaned = Normalizer.normalize(cleaned, Normalizer.Form.NFD) 

    // remove all characters that combine with the previous character 
    // to form a diacritic. Also remove control characters. 
    // http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html 
    cleaned.replaceAll("[\\p{InCombiningDiacriticalMarks}\\p{Cntrl}]", "") 

    // size must not change 
    require(cleaned.size == string.size) 

    cleaned 
    } 

    val substitutions = Set(
     (0x00AB, '"'), 
     (0x00AD, '-'), 
     (0x00B4, '\''), 
     (0x00BB, '"'), 
     (0x00F7, '/'), 
     (0x01C0, '|'), 
     (0x01C3, '!'), 
     (0x02B9, '\''), 
     (0x02BA, '"'), 
     (0x02BC, '\''), 
     (0x02C4, '^'), 
     (0x02C6, '^'), 
     (0x02C8, '\''), 
     (0x02CB, '`'), 
     (0x02CD, '_'), 
     (0x02DC, '~'), 
     (0x0300, '`'), 
     (0x0301, '\''), 
     (0x0302, '^'), 
     (0x0303, '~'), 
     (0x030B, '"'), 
     (0x030E, '"'), 
     (0x0331, '_'), 
     (0x0332, '_'), 
     (0x0338, '/'), 
     (0x0589, ':'), 
     (0x05C0, '|'), 
     (0x05C3, ':'), 
     (0x066A, '%'), 
     (0x066D, '*'), 
     (0x200B, ' '), 
     (0x2010, '-'), 
     (0x2011, '-'), 
     (0x2012, '-'), 
     (0x2013, '-'), 
     (0x2014, '-'), 
     (0x2015, '-'), 
     (0x2016, '|'), 
     (0x2017, '_'), 
     (0x2018, '\''), 
     (0x2019, '\''), 
     (0x201A, ','), 
     (0x201B, '\''), 
     (0x201C, '"'), 
     (0x201D, '"'), 
     (0x201E, '"'), 
     (0x201F, '"'), 
     (0x2032, '\''), 
     (0x2033, '"'), 
     (0x2034, '\''), 
     (0x2035, '`'), 
     (0x2036, '"'), 
     (0x2037, '\''), 
     (0x2038, '^'), 
     (0x2039, '<'), 
     (0x203A, '>'), 
     (0x203D, '?'), 
     (0x2044, '/'), 
     (0x204E, '*'), 
     (0x2052, '%'), 
     (0x2053, '~'), 
     (0x2060, ' '), 
     (0x20E5, '\\'), 
     (0x2212, '-'), 
     (0x2215, '/'), 
     (0x2216, '\\'), 
     (0x2217, '*'), 
     (0x2223, '|'), 
     (0x2236, ':'), 
     (0x223C, '~'), 
     (0x2264, '<'), 
     (0x2265, '>'), 
     (0x2266, '<'), 
     (0x2267, '>'), 
     (0x2303, '^'), 
     (0x2329, '<'), 
     (0x232A, '>'), 
     (0x266F, '#'), 
     (0x2731, '*'), 
     (0x2758, '|'), 
     (0x2762, '!'), 
     (0x27E6, '['), 
     (0x27E8, '<'), 
     (0x27E9, '>'), 
     (0x2983, '{'), 
     (0x2984, '}'), 
     (0x3003, '"'), 
     (0x3008, '<'), 
     (0x3009, '>'), 
     (0x301B, ']'), 
     (0x301C, '~'), 
     (0x301D, '"'), 
     (0x301E, '"'), 
     (0xFEFF, ' ')).map { case (unicode, ascii) => (unicode.toChar.toString, ascii.toString) } 
} 
+0

バグがあります: 'replaceAll'は文字列を変更しません。 'replaceAll'の結果をcleanedに戻す必要があります。 – slawek

関連する問題