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 回答