1

コーパス内の単語のリストの数を個別にカウントするために、Java で grep を呼び出しています。

BufferedReader fb = new BufferedReader(
 new InputStreamReader(   
  new FileInputStream("french.txt"), "UTF8"));

while ((l = fb.readLine()) != null){
String lpt = "\\b"+l+"\\b";
String[] args = new String[]{"grep","-ic",lpt,corpus};
Process grepCommand = Runtime.getRuntime().exec(args);
grep.waitFor()
}
BufferedReader grepInput = new BufferedReader(new InputStreamReader(grep.getInputStream()));
int tmp = Integer.parseInt(grepInput.readLine());
System.out.println(l+"\t"+tmp);

これは、私の英語の単語リストとコーパスに適しています。しかし、私はフランス語の単語リストとコーパスも持っています。フランス語では機能せず、Java コンソールでのサンプル出力は次のようになります。

� bord      0
� c�t�      0

正しい形は「à bord」と「à côté」です。

今私の質問は次のとおりです。問題はどこにありますか? Java コードを修正する必要がありますか、それとも grep の問題ですか? もしそうなら、どうすれば修正できますか。(エンコーディングを UTF-8 に変更しても、端末でフランス語の文字が正しく表示されません)。

4

2 に答える 2

0

ファイルを1行ずつ読んでsplitから、単語境界を呼び出して単語数を取得することをお勧めします。

public static void main(String[] args) throws IOException {
    final File file = new File("myFile");
    try (final BufferedReader bufferedReader =
            new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            final String[] words = line.split("\\b");
            System.out.println(words.length + " words in line \"" + line + "\".");
        }
    }
}

これにより、プログラムからの grep の呼び出しが回避されます。

あなたが得ている奇妙な文字は、間違ったエンコーディングを使用している可能性があります. ファイルが「UTF-8」であることは確かですか?

編集

OPは、1つのファイルを1行ずつ読み取り、別のファイルで読み取り行の出現を検索したいと考えています。

これは、Java を使用するとさらに簡単に実行できます。他のファイルの大きさに応じて、最初にメモリに読み込んで検索するか、行ごとに検索することもできます

ファイルをメモリに読み込む簡単な例:

public static void main(String[] args) throws UnsupportedEncodingException, IOException {
    final File corpusFile = new File("corpus");
    final String corpusFileContent = readFileToString(corpusFile);
    final File file = new File("myEngramFile");
    try (final BufferedReader bufferedReader =
            new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            final int matches = countOccurencesOf(line, corpusFileContent);
        };
    }
}

private static String readFileToString(final File file) throws IOException {
    final StringBuilder stringBuilder = new StringBuilder();
    try (final FileChannel fc = new RandomAccessFile(file, "r").getChannel()) {
        final ByteBuffer byteBuffer = ByteBuffer.allocate(4096);
        final CharsetDecoder charsetDecoder = Charset.forName("UTF-8").newDecoder();
        while (fc.read(byteBuffer) > 0) {
            byteBuffer.flip();
            stringBuilder.append(charsetDecoder.decode(byteBuffer));
            byteBuffer.reset();
        }
    }
    return stringBuilder.toString();
}

private static int countOccurencesOf(final String countMatchesOf, final String inString) {
    final Matcher matcher = Pattern.compile("\\b" + countMatchesOf + "\\b").matcher(inString);
    int count = 0;
    while (matcher.find()) {
        ++count;
    }
    return count;
}

「コーパス」ファイルが 100 メガバイト程度未満の場合、これは正常に機能するはずです。それ以上の場合は、「countOccurencesOf」メソッドを次のように変更する必要があります

private static int countOccurencesOf(final String countMatchesOf, final File inFile) throws IOException {
    final Pattern pattern = Pattern.compile("\\b" + countMatchesOf + "\\b");
    int count = 0;
    try (final BufferedReader bufferedReader =
            new BufferedReader(new InputStreamReader(new FileInputStream(inFile), "UTF-8"))) {
        String line;
        while ((line = bufferedReader.readLine()) != null) {
            final Matcher matcher = pattern.matcher(line);
            while (matcher.find()) {
                ++count;
            }
        };
    }
    return count;
}

ここで、文字列化されたファイルではなく、「ファイル」オブジェクトをメソッドに渡すだけです。

ストリーミング アプローチでは、ファイルが 1 行ずつ読み取られるため、改行が削除されることに注意してください。改行が存在することに依存しているString場合は、解析する前に改行を追加し直す必要があります。Pattern

于 2013-04-07T16:41:39.380 に答える