Использование регулярного выражения для поиска строки, совпадающей с несколькими словами, расположенными в случайном порядке - PullRequest
3 голосов
/ 02 апреля 2010

Как мне написать регулярное выражение для сопоставления нескольких слов в случайном порядке?

Например, предположим, что следующие строки:

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

Я хочу найти строку, соответствующую "Dave", "Imma" и "Dive", ожидая 1-ю и 4-ю строчки. Это возможно?

Ответы [ 5 ]

3 голосов
/ 04 апреля 2010

Если вы настаиваете на этом с регулярным выражением, вы можете использовать lookahead:

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

Regex - не самый эффективный способ сделать это.

2 голосов
/ 04 апреля 2010

в * nix, вы можете использовать awk

, если он в порядке

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

, если он не в порядке

awk '/Dave/ && /Imma/ && /Dive/' file
0 голосов
/ 04 апреля 2010

Должны ли совпадать следующие строки?

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

Пока что единственным другим ответом, который обеспечивает как уникальность, так и полные слова, является ответ Короната, и он не может сопоставить строки с дополнительными словами, как эти:

Dave Imma Car Pom Dive
Pyro Dave Imma Dive
0 голосов
/ 02 апреля 2010
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
}
0 голосов
/ 02 апреля 2010
if  ((matches "/(Dave|Imma|Dive) (Dave|Imma|Dive) (Dave|Imma|Dive)/")
 && (contains("Dave")) && (contains("Imma")) && (contains("Dive")))
{
    // this will work in 90% of cases.
}

Я не думаю, что это возможно сделать точно. К сожалению.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...