2012-12-17 11 views
24

Próbuję utworzyć funkcję wyszukiwania dla projektu, który zawęża elementy na podstawie danych wprowadzonych przez użytkownika i jeśli pasuje do słów kluczowych wymienionych w odniesieniu do elementów. W tym celu zapisuję słowa kluczowe przedmiotu w atrybucie data i dopasowuję zapytanie do tych słów kluczowych, używając wzorca RegExp.Wyrażenie regularne, aby dopasować WSZYSTKIE wyrazy w zapytaniu, w dowolnej kolejności

obecnie używam tego wyrażenia, które znam nie jest poprawna i potrzebują twojej pomocy na ten temat:

new RegExp('\\b(' + query + ')', 'gi'))) gdzie zapytania | oddzielone wartości zapytania wprowadzone przez użytkownika (np \\b(meat|pasta|dinner)). To powraca do mnie mecz, nawet jeśli jest tylko 1 mecz, powiedzmy na przykład - meat

Wystarczy rzucić pewien kontekst, oto mały przykład:

Jeśli użytkownik wpisze: meat pasta dinner należy wymienić wszystkie elementy, które mają WSZYSTKIE 3 słowa kluczowe wymieniane przeciwko nim, tj. meatpasta i dinner. Są one niezależne od kolejności, w jakiej zostały wpisane.

Czy możesz mi pomóc z wyrażeniem, które dopasuje WSZYSTKIE słowa w zapytaniu, w dowolnej kolejności?

+0

Umm, nie do końca - Muszę dopasować cały tekst wprowadzany przez użytkownika ze słowami kluczowymi do elementów i zwracać wartość true, jeśli całe wejście pasuje do słów kluczowych tych elementów. – kayen

+0

Zasadniczo muszę wymyślić wyrażenie AND, które będzie ORAZ użytkownik wprowadził 'np. kolację z mięsem "i sprawdzić pod kątem słów kluczowych" np. Makaron kebabu mięsnego mięsnego kontynentalnego pasztetowy prosty '. W tym przypadku wyrażenie nie powiedzie się, ponieważ słowo kluczowe zawiera "mięso" i "ciasto", ale nie "obiad". – kayen

+1

Dlaczego nie używasz prostej metody 'string'? Chodzi mi o to, że jeśli nie ma powtarzających się słów kluczowych, to można to łatwo osiągnąć dzięki Regexowi.Ale z powtarzającymi się słowami kluczowymi, lepiej unikać Regex tutaj. Po prostu użyj funkcji 'indexOf' z pętlą for. Lub może być lepszą funkcją String, której być może nie jestem świadomy. –

Odpowiedz

49

Można to osiągnąć będzie uprzedzona twierdzeń

^(?=.*\bmeat\b)(?=.*\bpasta\b)(?=.*\bdinner\b).+ 

Zobacz here on Regexr

(?=.*\bmeat\b) jest positive lookahead assertion, który zapewnia, że ​​\bmeat\b jest gdzieś w łańcuchu. To samo dotyczy innych słów kluczowych, a .+ dopasowuje wtedy cały ciąg, ale tylko wtedy, gdy twierdzenia są prawdziwe.

Ale to pasuje również na „obiad mięso foobar pasta”

4

Twój regex wygląda całkiem nieźle:

\b(meat|pasta|dinner)\b 

Sprawdź, czy długość dopasowania równa liczbie słów kluczowych (w tym przypadku trzy):

string.match(re).length === numberOfKeywords 

gdzie re jest regex z g flaga, string to dane, a numberOfKeywords to liczba słów kluczowych

Zakłada się, że nie powtarzaj słów kluczowych.

+0

W tym modelu duplikaty również należy usunąć – closure

+0

Dzięki za pomoc! Ale tak, słowa kluczowe mogą się powtarzać, więc będę kontynuował odpowiedź powyżej. +1 dla logiki. – kayen

+0

Również jeśli potrzebujesz warunku dla co najmniej "X" przedmiotów, gdzie "X" oznacza zakres początkowy, wtedy możesz użyć poniższego wyrażenia regularnego (zmodyfikowanego dla co najmniej jednego przedmiotu) \ b (mięso | makaron | obiad) {1,3} \ b – vCillusion

1

podstawie zaakceptowanych odpowiedzi napisałem prostą metodę Java, który buduje regex z tablicy słów kluczowych

public static String regexIfAllKeywordsExists(String[] keywords) { 
    StringBuilder sb = new StringBuilder("^"); 

    for (String keyword : keywords) { 
     sb.append("(?=.*\\b"); 
     sb.append(keyword); 
     sb.append("\\b)"); 
    } 

    sb.append(".+"); 

    return sb.toString(); 
} 
Powiązane problemy