如何选择2个单词之间有3个以上字符的单词

时间:2013-01-16 23:52:45

标签: regex regex-negation regex-lookarounds

下面的文字是使用正则表达式从大文本中过滤掉的,我必须找到没有猪和猪的狗和猫的句子。

What, a Dog, a Rat, a Mouse, a Cat to scratch a man to
Where Iuliet liues, and euery Cat and Dog,
Which first (perchance) shee'l proue on Cats and Dogs,
glass, and from setting up memorials of departed cats and dogs.
Thinking,' etc., 1873, p. 82.), "A dog frames a general concept of cats or
dog, who never passed a cat who lay sick in a basket, and was a great

要找到上面的内容,我使用了正则表达式:

^(?!.\*porc.\*)(?!.\*pig.\*)(?=.\*\bdog\b.\*)(?=.\*\bcat\b.\*).\*

现在,我必须在狗和猫之间找到3个字符以上的单词。

我试过了:

^(?!.\*porc.\*)(?!.\*pig.\*)(?=.\*\bdog\b.\*)(?=.\*\bcat\b.\*)dog(?:\s?\w{3,})+cat

它不起作用。

任何人都知道如何解决它?

1 个答案:

答案 0 :(得分:0)

让我先说明我对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和其他允许捕获重复组的语言不同),您很可能需要分两步执行查询。首先,您需要找到猫(猫)或狗(狗)或猫(猫)之间的所有字符串(只要第一组不像第二组)。您可以使用如下的正则表达式找到这些字符串:

(?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组后,您可能希望使用以下内容(基于this post):

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之间会出现多少个三个字母单词。我希望这会有所帮助。