使用regexp搜索匹配随机排列的多个单词的字符串

时间:2010-04-02 05:56:34

标签: regex

如何编写正则表达式以便按随机顺序匹配多个单词?

例如,我们假设以下几行:

Dave Imma Car Pom Dive
Dive Dome Dare
Imma Car Ryan
Pyro Dave Imma Dive
Lunar Happy Dave

我想在字符串中搜索匹配“Dave”“Imma”和“Dive”的字符串,期待第1行和第4行。这可能吗?

5 个答案:

答案 0 :(得分:3)

如果您坚持使用正则表达式执行此操作,则可以使用前瞻:

s.matches("(?=.*Dave)(?=.*Imma)(?=.*Dive).*")

但是,正则表达式不是最有效的方法。

答案 1 :(得分:2)

在* nix中,你可以使用awk

如果按顺序

awk '/Dave.*Imma.*Dive/' file

如果不按顺序

awk '/Dave/ && /Imma/ && /Dive/' file

答案 2 :(得分:0)

if  ((matches "/(Dave|Imma|Dive) (Dave|Imma|Dive) (Dave|Imma|Dive)/")
 && (contains("Dave")) && (contains("Imma")) && (contains("Dive")))
{
    // this will work in 90% of cases.
}
但是,我认为不可能完全做到这一点。遗憾。

答案 3 :(得分:0)

String[] lines = fullData.split("\n");
String[] names = {"Dave", "Imma", "Dive"};
ArrayList matches = new ArrayList();

for(int i=0; i<lines.size(); i++){
    for(String name : names){
        // If any of the names in the list isn't found
        // then this line isn't a match
        if(!lines[i].contains(name)){
            continue;
        }
    }
    // If we made it this far, all of the names were found
    matches.add(i);
}
// matches now contains {1, 4}

如果您不需要知道匹配的位置,可将其简化为:

String[] lines = fullData.split("\n");
String[] names = {"Dave", "Imma", "Dive"};

for(String line : lines){
    for(String name : names){
        // If any of the names in the list isn't found
        // then this line isn't a match
        if(!line.contains(name)){
            continue;
        }
    }
    // If we made it this far, all of the names were found

    // Do something
}

答案 4 :(得分:0)

以下行是否匹配?

Dave Imma Dave
Dave Imma Dive Imma

我猜第一个不应该因为它不包含所有三个名字,但重复是否正常?如果没有,这个正则表达式就可以了:

^(?:\b(?:(?!(?:Dave|Imma|Dive)\b)\w+[ \t]+)*(?:Dave()|Imma()|Dive())[ \t]*){3}$\1\2\3

我建议使用“技巧”这个词。 :)这证明正则表达式可以完成这项工作,但我不希望在任何严肃的应用程序中看到这个正则表达式。为此目的编写方法会好得多。

(顺便说一句,如果允许重复 ,只需删除$。)

编辑:另一个问题:名称是否应仅以完整单词的形式匹配?换句话说,这些行应该匹配吗?

DaveCar PomDive Imma
DaveImmaDive

到目前为止,唯一能够强制执行唯一性和完整单词的其他答案是Coronatus,并且它无法匹配具有额外单词的行,如下所示:

Dave Imma Car Pom Dive
Pyro Dave Imma Dive