40,000 行あり、各行を異なる文に分割する必要があります。今、私はこのようなパターンを使用しています:
String patternStr2 = "\\s*[\"']?\\s*([A-Z0-9].*?[\\.\\?!]\\s)['\"]?\\s*";
ほとんどすべての文を処理できますが、次のような文の場合: US Navy, World War I. は 2 つの部分に分けられます: US and Navy, World War I.
この問題を処理する解決策はありますか?
40,000 行あり、各行を異なる文に分割する必要があります。今、私はこのようなパターンを使用しています:
String patternStr2 = "\\s*[\"']?\\s*([A-Z0-9].*?[\\.\\?!]\\s)['\"]?\\s*";
ほとんどすべての文を処理できますが、次のような文の場合: US Navy, World War I. は 2 つの部分に分けられます: US and Navy, World War I.
この問題を処理する解決策はありますか?
これには正規表現を使用しないでください。
これがわかりにくい場合はお知らせください。コメントを追加します...
package test;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
private static final Pattern SENTENCE_DELIMITER =
Pattern.compile("((.+?)((?<!\\.[A-Z])(\\.\\s)(.+))?)");
public static void main(String[] args) {
String lineWithOneSentence =
"U.S. Navy, World War I";
String lineWithTwoSentences =
"U.S. Navy, World War I. U.S. Air Force, World War III.";
Matcher matcher = SENTENCE_DELIMITER.matcher(lineWithOneSentence);
if (matcher.matches()) {
for (int i = 0; i <= matcher.groupCount(); i++) {
switch (i) {
case 0:
System.out.println("WHOLE MATCH: " + matcher.group(i));
break;
case 2:
System.out.println("FIRST SENTENCE: "+ matcher.group(i));
break;
case 5:
System.out.println("SECOND SENTENCE: " + matcher.group(i));
default:
}
}
}
matcher = SENTENCE_DELIMITER.matcher(lineWithTwoSentences);
if (matcher.matches()) {
for (int i = 0; i <= matcher.groupCount(); i++) {
switch (i) {
case 0:
System.out.println("WHOLE MATCH: " + matcher.group(i));
break;
case 2:
System.out.println("FIRST SENTENCE: "+ matcher.group(i));
break;
case 5:
System.out.println("SECOND SENTENCE: " + matcher.group(i));
default:
}
}
}
}
}
ここでの回避策は次のとおりです。
これはかなりやり過ぎで、おそらくある時点で問題になるでしょう。つまり、テキストが句読点ごとに一貫していない場合などです。
出力:
WHOLE MATCH: U.S. Navy, World War I
FIRST SENTENCE: U.S. Navy, World War I
SECOND SENTENCE: null
WHOLE MATCH: U.S. Navy, World War I. U.S. Air Force, World War III.
FIRST SENTENCE: U.S. Navy, World War I
SECOND SENTENCE: U.S. Air Force, World War III.
分割したいのに、なぜ一致させようとしているのですか?
次の正規表現を使用します。
(?<!\..)\.(?!.\.)
説明:
(?<!\..)
:否定後読み、2文字後ろにポイントがないかチェック。
\.
: ポイントを合わせます。
(?!.\.)
:否定先読み、2文字先に点がないかチェック。
注: JAVA でこれを行う方法はわかりませんが、試してみるとよいと思います(?<!\\..)\\.(?!.\\.)
。また、分割した文章にポイントを追加することを忘れないでください。
文字列 patternStr2 = " (?<!\\..)(?<![A-Z].)[\\.\\?!](?!.\\.)
"; その後、Java Matcher の find() メソッドを使用すると、すべての文を取得できます。