Java についての私の知識は最高ではないと言って前置きさせてください (私は言語の所属が宣言される前に質問に答えました)。そうは言っても、(私の知る限り)Javaは繰り返されるグループのキャプチャをサポートしていないため、問題には2つの正規表現が必要だと思います。必要なものを説明するために、探している全体的なパターンを検討してください。最初の例 (「なに、犬、ネズミ、ネズミ、人をひっかく猫」) の一致を 2 つのアスタリスクで含めました。
(?P<animal> // Names the following group "animal" for later reference
\b(dog|cat) // **Dog**
) // Ends "animal" group
[s]?\b\W+ // **, **
(?!\bporc\b\W+|\bpig\b\W+|(?P=animal)\W+) // Not followed by porc, pig, or characters that match group "animal" (either 'cat' or 'dog')
.*? // Characters up to first word of three characters or more **a **
(
(
(
(
(\b\w{3,}\b) // The (repeated) group you are after (**Rat** / **Mouse**)
\W+)+ // (**, ** / **, **)
)
(?:\b\w{0,2}\b\W+)* // A group that will not be available after the search (**a ** / **a **)
)+
)
(?! // Not followed by
(?P=animal) // the characters that matched group "animal" above (either dog or cat)
)\b
(cat|dog)[s]{0,1}\b // Followed by dog or cat, whichever was not the "animal" group above **Cat**
Java は繰り返されるグループの最後のもののみをキャプチャするため (.NET や他の言語で繰り返しグループをキャプチャできるのとは異なります)、おそらく 2 つのステップでクエリを実行する必要があります。最初に、cat(s) または dog(s) と dog(s) または cat(s) の間のすべての文字列を見つける必要があります (グループ 1 がグループ 2 と異なる場合に限ります)。これらの文字列は、次のような正規表現で見つけることができます。
(?P<animal>\b(dog|cat))[s]{0,1}\b\W+(?!\bporc\b\W+|\bpig\b\W+|(?P=animal)\W+)(.*?)(?!(?P=animal))\b(cat|dog)[s]{0,1}\b
(.*?) であるグループ 3 を検索します。
関連する各文字列/文でグループ 3 を特定したら、次のようなものを使用する必要があります (この投稿に基づく)。
Pattern regex = Pattern.compile("\b\w{3,}\b");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
// matched text: regexMatcher.group()
// match start: regexMatcher.start()
// match end: regexMatcher.end()
}
残念ながら、犬と猫という単語の間に 3 文字の単語がいくつあるか分からないため、1 つの (合理的な) 正規表現だけを使用して Java で必要なすべての単語を取得することはできません。これが役立つことを願っています。