Verwendung von Regex in der String.contains () -Methode in Java

112

Ich möchte überprüfen, ob ein String die Wörter "speichert", "speichern" und "Produkt" in dieser Reihenfolge enthält, unabhängig davon, was sich dazwischen befindet.

Ich habe versucht, someString.contains(stores%store%product);und auch.contains("stores%store%product");

Muss ich einen regulären Ausdruck explizit deklarieren und an die Methode übergeben, oder kann ich einen regulären Ausdruck überhaupt nicht übergeben?

vipin8169
quelle

Antworten:

125

String.contains

String.containsarbeitet mit String, Punkt. Es funktioniert nicht mit Regex. Es wird geprüft, ob die genaue angegebene Zeichenfolge in der aktuellen Zeichenfolge angezeigt wird oder nicht.

Beachten Sie, dass String.containsnicht nach Wortgrenzen gesucht wird. es wird einfach nach Teilzeichenfolgen gesucht.

Regex-Lösung

Regex ist leistungsfähiger als String.contains, da Sie (unter anderem) Wortgrenzen für die Schlüsselwörter erzwingen können. Dies bedeutet, dass Sie nach den Schlüsselwörtern als Wörter und nicht nur nach Teilzeichenfolgen suchen können .

Verwenden Sie String.matchesmit dem folgenden regulären Ausdruck:

"(?s).*\\bstores\\b.*\\bstore\\b.*\\bproduct\\b.*"

Die RAW-Regex (entfernen Sie das im Zeichenfolgenliteral vorgenommene Escapezeichen - dies erhalten Sie, wenn Sie die obige Zeichenfolge ausdrucken):

(?s).*\bstores\b.*\bstore\b.*\bproduct\b.*

Die \bprüft auf Wortgrenze, damit Sie keine Übereinstimmung für bekommen restores store products. Beachten Sie, dass dies stores 3store_productebenfalls abgelehnt wird, da Ziffern und _als Teil eines Wortes betrachtet werden, aber ich bezweifle, dass dieser Fall im natürlichen Text erscheint.

Da die Wortgrenze für beide Seiten aktiviert ist, sucht der Regex oben nach genauen Wörtern. Mit anderen Worten, stores stores productstimmt nicht mit dem obigen regulären Ausdruck überein, da Sie nach dem Wort storeohne suchen s.

.Normalerweise stimmen alle Zeichen mit Ausnahme einiger neuer Zeilenzeichen überein . (?s)zu Beginn .passt jeder Charakter ausnahmslos zusammen (danke an Tim Pietzcker für den Hinweis).

nhahtdh
quelle
7
Möglicherweise möchten Sie (?s)den Anfang Ihrer Regex hinzufügen , falls die Zeichenfolge Zeilenumbrüche enthält.
Tim Pietzcker
Ich überprüfe es in einer URL wie dieser >> store.nextag.com/store/4908844/product/1070625777/…
vipin8169
\\b
Können
1
@ vipin8169: In String, müssen Sie die verdoppeln \einen einzelnen angeben \, so \\bwird als interpretiert werden \b, wie in der RAW - regex gesehen. \bentspricht der Wortgrenze, wie oben erläutert.
nhahtdh
wenn nötig ".mydomain". in string. Wie würde es dann den regulären Ausdruck aktualisieren? Mein Anwendungsfall ist, ob "www.abc.mydomain.in.io" die .mydomain enthält. oder nicht
Manmohan Soni
111

matcher.find()macht was du brauchst. Beispiel:

Pattern.compile("stores.*store.*product").matcher(someString).find();
eugene82
quelle
4
Ich liebe diesen. Ich finde Matcher's Regex zu kompliziert.
Mathter
21

Sie können einfach die matchesMethode der String-Klasse verwenden.

boolean result = someString.matches("stores.*store.*product.*");
san1deep2set3hi
quelle
14
Sie müssen mit beginnen, .*sonst werden nur Zeichenfolgen abgeglichen, die mit beginnen stores.
Shmosel
Versuche, die gesamte Region mit dem Muster abzugleichen. Es scheint, dass @shmosel richtig ist, nein?
Pieter De Bie
1
Nun, es stimmt nur überein , prüft aber nicht, ob die Zeichenfolge das Muster an einer beliebigen Position enthält. Dies ist keine Lösung, nach der OP sucht. Ich schlage vor, den regulären Ausdruck zu verfeinern.
Gee Bee
2

Wenn Sie überprüfen möchten, ob eine Zeichenfolge Teilzeichenfolgen enthält oder keinen regulären Ausdruck verwendet, können Sie am besten find () - verwenden.

    private static final validPattern =   "\\bstores\\b.*\\bstore\\b.*\\bproduct\\b"
    Pattern pattern = Pattern.compile(validPattern);
    Matcher matcher = pattern.matcher(inputString);
    System.out.print(matcher.find()); // should print true or false.

Beachten Sie den Unterschied zwischen Übereinstimmungen () und find (). Übereinstimmungen () geben true zurück, wenn die gesamte Zeichenfolge mit dem angegebenen Muster übereinstimmt. find () versucht, einen Teilstring zu finden, der dem Muster in einer bestimmten Eingabezeichenfolge entspricht. Wenn Sie find () verwenden, müssen Sie auch keine zusätzlichen Übereinstimmungen wie - (? S). * Am Anfang und. * Am Ende Ihres Regex-Musters hinzufügen.

PC
quelle
2
public static void main(String[] args) {
    String test = "something hear - to - find some to or tows";
    System.out.println("1.result: " + contains("- to -( \\w+) som", test, null));
    System.out.println("2.result: " + contains("- to -( \\w+) som", test, 5));
}
static boolean contains(String pattern, String text, Integer fromIndex){
    if(fromIndex != null && fromIndex < text.length())
        return Pattern.compile(pattern).matcher(text).find();

    return Pattern.compile(pattern).matcher(text).find();
}

1. Ergebnis: wahr

2. Ergebnis: wahr

Ar maj
quelle
fromIndexwird ignoriert, nicht wahr? contains("something", test, 5) => true
PKeidel