Comment utiliser regex dans la méthode String.contains () en Java

112

Je veux vérifier si une chaîne contient les mots "stores", "store" et "product" dans cet ordre, peu importe ce qui se trouve entre eux.

J'ai essayé d'utiliser someString.contains(stores%store%product);et aussi.contains("stores%store%product");

Dois-je explicitement déclarer une expression régulière et la transmettre à la méthode ou ne puis-je pas du tout passer une expression régulière?

vipin8169
la source

Réponses:

125

String.contains

String.containsfonctionne avec String, point final. Cela ne fonctionne pas avec regex. Il vérifiera si la chaîne exacte spécifiée apparaît ou non dans la chaîne actuelle.

Notez que String.containscela ne vérifie pas la limite du mot; il vérifie simplement la sous-chaîne.

Solution regex

Regex est plus puissant que String.contains, puisque vous pouvez appliquer une limite de mot sur les mots-clés (entre autres). Cela signifie que vous pouvez rechercher les mots-clés sous forme de mots , plutôt que de simples sous - chaînes .

À utiliser String.matchesavec l'expression rationnelle suivante:

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

Le regex RAW (supprimez l'échappement effectué dans la chaîne littérale - c'est ce que vous obtenez lorsque vous imprimez la chaîne ci-dessus):

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

Les \bvérifications de la limite du mot, de sorte que vous n'obteniez pas de correspondance restores store products. Notez que stores 3store_productc'est également rejeté, car digit et _sont considérés comme faisant partie d'un mot, mais je doute que ce cas apparaisse dans le texte naturel.

Puisque la limite de mot est vérifiée pour les deux côtés, l'expression régulière ci-dessus recherchera des mots exacts. En d'autres termes, stores stores productne correspondra pas à l'expression régulière ci-dessus, car vous recherchez le mot storesans s.

.correspond normalement à n'importe quel caractère sauf un certain nombre de caractères de nouvelle ligne . (?s)au début fait des .correspondances avec n'importe quel caractère sans exception (merci à Tim Pietzcker pour l'avoir signalé).

nhahtdh
la source
7
Vous voudrez peut-être ajouter (?s)au début de votre expression régulière au cas où la chaîne contiendrait des sauts de ligne.
Tim Pietzcker
Je vérifie dans une URL comme celle-ci >> stores.nextag.com/store/4908844/product/1070625777/…
vipin8169
pouvez-vous expliquer le premier backslash ici\\b
vipin8169
1
@ vipin8169: Dans String, vous devez doubler le \pour en spécifier un seul \, il \\bsera donc interprété comme \b, comme indiqué dans l'expression régulière RAW. \bcorrespond à la limite du mot, comme expliqué ci-dessus.
nhahtdh
si besoin correspond à ".mydomain." en chaîne. alors comment mettrait-il à jour le regex. Mon cas d'utilisation est de savoir si "www.abc.mydomain.in.io" contient le .mydomain. ou pas
Manmohan Soni
111

matcher.find()fait ce dont vous aviez besoin. Exemple:

Pattern.compile("stores.*store.*product").matcher(someString).find();
eugene82
la source
4
J'aime celui-ci. Je trouve l'expression régulière de matcher trop compliquée.
Mathter
21

Vous pouvez simplement utiliser la matchesméthode de la classe String.

boolean result = someString.matches("stores.*store.*product.*");
san1deep2set3hi
la source
14
Vous devez commencer par .*ou cela ne correspondra qu'aux chaînes commençant par stores.
shmosel
Tente de faire correspondre toute la région au modèle. Il semble que @shmosel a raison, non?
Pieter De Bie
1
Eh bien, il correspond juste mais ne vérifie pas si la chaîne contient le motif à n'importe quelle position. Ce n'est pas une solution recherchée par OP, je suggère d'affiner l'expression rationnelle.
Gee Bee
2

Si vous voulez vérifier si une chaîne contient une sous-chaîne ou si vous n'utilisez pas de regex, le plus proche que vous pouvez faire est d'utiliser find () -

    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.

Notez la différence entre matches () et find (), matches () retournent true si la chaîne entière correspond au modèle donné. find () essaie de trouver une sous-chaîne qui correspond au modèle dans une chaîne d'entrée donnée. De plus, en utilisant find (), vous n'avez pas à ajouter de correspondance supplémentaire comme - (? S). * Au début et. * À la fin de votre modèle d'expression régulière.

PC
la source
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. résultat: vrai

2. résultat: vrai

Ar maj
la source
fromIndexest ignoré, n'est-ce pas? contains("something", test, 5) => true
PKeidel