0

マルチバイト文字を含むファイルがあります。ファイルが非常に大きいため、このファイルから4バイトのutf文字を削除したいと思います。それを行うには、より高速なソリューションが必要です。このタスクで次のJavaコードを試しましたが、Javaヒープスペースのメモリ不足例外が発生します。それで

import java.util.*;
import java.io.*;
public class A{
 public static void main(String args[]) throws Exception{
  BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
  String str=br.readLine();
  char[] c_array;
  String c_string;
  byte[] c_byte_array;
  c_array = str.toCharArray();
  for (char c : c_array){
   c_string = Character.toString(c);
   c_byte_array = c_string.getBytes("UTF-8");
   if (c_byte_array.length <= 3){
    System.out.print(c_string);
   }
  }
 }
}

これまたは他のより速くより良い方法を改善する方法はありますか?このgrepコマンドも試しました

grep -o -P "[\x10000-\x10ffff]" myfile

しかし、それはエラーで終了します

grep: range out of order in character class

だから私の質問は、上記の正規表現の何が問題なのかということです。つまり、4バイトのutf文字に一致する正規表現とは何ですか。上記の方法のどれが4バイト文字を削除するのにより効率的であるかという別の質問

4

1 に答える 1

11

UTF-8 4 バイト文字は、U+FFFF を超える Unicode 文字 ( http://en.wikipedia.org/wiki/UTF-8を参照) であり、Java では 2 文字で表されます。Character.isSurrogate (API を参照) を使用して、そのような文字を検出できます。

    BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream("1.txt"), "UTF-8"));
    for (int c; (c = br.read()) != -1;) {
        if (Character.isSurrogate((char)c)) {
            // skip the second surrogate char
            br.read();
        } else {
            // process char c
        }
    }

または、バイト ストリームをフィルタリングする場合は、4 バイト文字の UTF-8 シーケンスが

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

バイトストリームを次のようにフィルタリングできます

   BufferedInputStream is = new BufferedInputStream(new FileInputStream("1.txt"));
    for (int b; (b = is.read()) != -1;) {
        if ((b & 0b11111000) == 0b11110000) {
            // skip next 3 bytes
            is.read();
            is.read();
            is.read();
        } else {
            // process byte b
        }
    }
于 2013-01-17T07:43:40.927 に答える