Como usar regex no método String.contains () em Java

112

Quero verificar se uma String contém as palavras "armazena", "armazena" e "produto" nessa ordem, não importa o que esteja entre elas.

Tentei usar someString.contains(stores%store%product);e também.contains("stores%store%product");

Preciso declarar explicitamente uma regex e passá-la no método ou não posso passar uma regex?

vipin8169
fonte

Respostas:

125

String.contains

String.containstrabalha com String, ponto final. Não funciona com regex. Ele verificará se a String exata especificada aparece na String atual ou não.

Observe que String.containsnão verifica o limite da palavra; ele simplesmente verifica a substring.

Solução Regex

Regex é mais poderoso do que String.contains, uma vez que você pode impor limites de palavras nas palavras-chave (entre outras coisas). Isso significa que você pode pesquisar as palavras-chave como palavras , em vez de apenas substrings .

Use String.matchescom o seguinte regex:

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

O regex RAW (remova o escape feito no literal de string - isso é o que você obtém quando imprime a string acima):

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

A \bverificação de limite de palavra, para que você não obtenha uma correspondência para restores store products. Observe que stores 3store_producttambém é rejeitado, uma vez que dígito e_ são considerados parte de uma palavra, mas eu duvido que esse caso apareça em texto natural.

Como o limite da palavra é verificado para ambos os lados, o regex acima irá pesquisar por palavras exatas. Em outras palavras, stores stores productnão corresponderá ao regex acima, pois você está procurando pela palavra storesem s.

.normalmente corresponde a qualquer caractere, exceto um número de caracteres de nova linha . (?s)no início faz .combinações com qualquer caractere sem exceção (obrigado a Tim Pietzcker por apontar isso).

nhahtdh
fonte
7
Você pode querer adicionar (?s)ao início de sua regex, caso a string contenha novas linhas.
Tim Pietzcker
estou verificando em um URL como este >> stores.nextag.com/store/4908844/product/1070625777/…
vipin8169
você pode explicar a primeira barra invertida aqui\\b
vipin8169
1
@ vipin8169: Em String, você precisa dobrar o \para especificar um único \, então \\bserá interpretado como \b, conforme visto no regex RAW. \bcorresponde ao limite da palavra, conforme explicado acima.
nhahtdh
se necessário corresponder a ".meudominio." na corda. em seguida, como ele atualizaria o regex. Meu caso de uso é se "www.abc.mydomain.in.io" contendo o .mydomain. ou não
Manmohan Soni
111

matcher.find()faz o que você precisava. Exemplo:

Pattern.compile("stores.*store.*product").matcher(someString).find();
eugene82
fonte
4
Amo este. Acho o regex do matcher muito complicado.
Mathter
21

Você pode simplesmente usar o matchesmétodo da classe String.

boolean result = someString.matches("stores.*store.*product.*");
san1deep2set3hi
fonte
14
Você precisa começar com, .*ou ele só corresponderá às strings que começam com stores.
shmosel
Tenta combinar toda a região com o padrão. Parece que @shmosel está certo, não?
Pieter De Bie,
1
Bem, ele apenas corresponde, mas não verifica se a string contém o padrão em qualquer posição. Esta não é uma solução que o OP procura, sugiro refinar o regexp.
Gee Bee
2

Se você quiser verificar se uma string contém substring ou não usando regex, o mais próximo que você pode fazer é usar 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.

Observe a diferença entre match () e find (), match () retorna verdadeiro se toda a string corresponder ao padrão fornecido. find () tenta encontrar uma substring que corresponda ao padrão em uma dada string de entrada. Além disso, usando find (), você não precisa adicionar correspondências extras como - (? S). * No início e. * No final de seu padrão regex.

PC
fonte
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. resultado: verdadeiro

2. resultado: verdadeiro

Ar maj
fonte
fromIndexé ignorado, não é? contains("something", test, 5) => true
PKeidel