让我先说我对 Java 的熟悉程度不是最好的(我在声明任何语言隶属关系之前回答了这个问题)。话虽如此,我认为您的问题将需要两个正则表达式,因为(据我所知)Java 不支持捕获重复组。为了说明您需要什么,请考虑您正在寻找的整体模式。我在双星号中包含了您第一个示例中的匹配项(“什么,一只狗,一只老鼠,一只老鼠,一只猫抓一个人”):
(?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 和其他允许捕获重复组的语言不同),因此您很可能需要分两步进行查询。首先,您需要找到 cat(s) or dog(s) 和 dog(s) or cat(s) 之间的所有字符串(只要第一组不同于第二组)。您可以使用如下的正则表达式找到这些字符串:
(?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()
}
不幸的是,您不能只使用一个(合理的)正则表达式来捕获 Java 中需要的所有单词,因为您永远不知道单词 dog 和 cat 之间会出现多少个三个字母的单词。我希望这有帮助。