1

似たような質問がたくさんありますが、すべて読んだと言えます。しかし、私は正規表現が苦手で、必要な正規表現を理解できませんでした。

Java で文字列を分割したいのですが、4 つの制約があります。

  1. 区切り文字は [.?!] (文末)
  2. 10 進数はトークン化しないでください
  3. 区切り文字は削除しないでください。
  4. 各トークンの最小サイズは 5 にする必要があります

たとえば、入力の場合:

"Hello World! This answer worth $1.45 in U.S. dollar. Thank you."

出力は次のようになります。

[Hello World!, This answer worth $1.45 in U.S. dollar., Thank you.]

今まで、この正規表現によって 3 つの最初の制約に対する答えを得ました。

text.split("(?<=[.!?])(?<!\\d)(?!\\d)");

そして{5,}、正規表現のどこかで使用する必要があることはわかっていますが、試した組み合わせは機能しません。

次のような場合:別の文として"I love U.S. How about you?"トークン化されない限り、1 つまたは 2 つの文が得られても問題ありませんS.

最後に、正規表現の優れたチュートリアルを紹介していただければ幸いです。

更新: Chrisがコメントで述べたよう に、正規表現を使用して (自然言語で発生するすべてのケースをカバーするために) このような質問を解決することはほとんど不可能です。ただし、HamZa の回答はクローゼットであり、最も有用なものであることがわかりました。

ので注意してください!受け入れられた回答は、考えられるすべてのユースケースをカバーするわけではありません!

4

2 に答える 2

2

以前に作成された regexからの私の答えに基づいています。
正規表現は基本的に、 、またはの(?<=[.?!])\s+(?=[a-z])いずれかが先行する任意の空白に 1 回以上一致することを意味します(修飾子を忘れないでください)。.?![a-z]i

次に、この質問のニーズに合わせて変更しましょう。

  1. まず、JAVA 正規表現に変換します。(?<=[.?!])\\s+(?=[a-z])
  2. i大文字と小文字を区別しない一致する修飾子を追加します(?i)(?<=[.?!])\\s+(?=[a-z])
  3. 文字 (この場合は区切り記号) の「食い込み」を防ぐために、式を肯定的な先読みにします。(?=(?i)(?<=[.?!])\\s+(?=[a-z]))
  4. 形式に省略形がないかどうかを確認するために、否定後読みを追加しますLETTER DOT LETTER DOT(?i)(?<=[.?!])(?<![a-z]\.[a-z]\.)\\s+(?=[a-z])

したがって、最終的な正規表現は : のようになります(?i)(?<=[.?!])(?<![a-z]\.[a-z]\.)\\s+(?=[a-z])

いくつかのリンク:

于 2013-08-16T21:22:08.343 に答える
2

次の正規表現は?

(?<=[.!?])(?!\w{1,5})(?<!\d)(?!\d)

例えば

private static final Pattern REGEX_PATTERN = 
        Pattern.compile("(?<=[.!?])(?!\\w{1,5})(?<!\\d)(?!\\d)");

public static void main(String[] args) {
    String input = "Hello World! This answer worth $1.45 in U.S. dollar. Thank you.";

    System.out.println(java.util.Arrays.toString(
        REGEX_PATTERN.split(input)
    )); // prints "[Hello World!,  This answer worth $1.45 in U.S.,  dollar.,  Thank you.]"
}
于 2013-08-16T20:41:36.983 に答える