O Java RegEx não diferencia maiúsculas de minúsculas?

111

Em Java, ao fazer um replaceAll para procurar um padrão regex como:

replaceAll("\\?i\\b(\\w+)\\b(\\s+\\1)+\\b", "$1"); 

(para remover palavras duplicadas consecutivas que não diferenciam maiúsculas de minúsculas, por exemplo, Teste de teste), não tenho certeza de onde coloquei o ?i. Eu li que deveria estar no início, mas se eu tirar, então eu detecto palavras consecutivas duplicadas (por exemplo, teste de teste), mas não palavras que não diferenciam maiúsculas de minúsculas (por exemplo, Teste de teste). Portanto, pensei que poderia adicionar o? I no início, mas isso não parece funcionar. Alguma ideia? Obrigado!

Cristal
fonte

Respostas:

119

RegexBuddy está me dizendo se você deseja incluí-lo no início, esta é a sintaxe correta:

"(?i)\\b(\\w+)\\b(\\s+\\1)+\\b"
Cnanney
fonte
168

Você também pode combinar regexs que não diferenciam maiúsculas de minúsculas e torná-las mais legíveis usando a constante Pattern.CASE_INSENSITIVE como:

Pattern mypattern = Pattern.compile(MYREGEX, Pattern.CASE_INSENSITIVE);
Matcher mymatcher= mypattern.matcher(mystring);
Christian Vielma
fonte
2
Mmmm .... operações OR inclusivas bit a bit ...Pattern.compile(myregex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE)
Nick Grealy 01 de
4
Isso é muito mais legível do que isso (?i), regexes Java já eram bastante ilegíveis: S
Bartek Banachewicz
Esta é a mesma resposta que a resposta de relet 4 anos antes, mas obtém todos os votos. Ímpar.
Zoomzoom
@Zoomzoom, não era quando eu escrevi :) se você verificar o histórico de edição do relet, verá que mudou para isso em 2018 stackoverflow.com/posts/3436124/…
Christian Vielma
126

Sim, a diferenciação de maiúsculas e minúsculas pode ser ativada e desativada à vontade no Java regex.

Parece que você quer algo assim:

    System.out.println(
        "Have a meRry MErrY Christmas ho Ho hO"
            .replaceAll("(?i)\\b(\\w+)(\\s+\\1)+\\b", "$1")
    );
    // Have a meRry Christmas ho

Observe que o sinalizador incorporado não Pattern.CASE_INSENSITIVEé . Observe também que um supérfluo foi removido do padrão.(?i)\?i\b

O (?i)é colocado no início do padrão para permitir a não diferenciação de maiúsculas e minúsculas. Nesse caso específico, ele não é substituído posteriormente no padrão; portanto, todo o padrão não diferencia maiúsculas de minúsculas.

É importante notar que, na verdade, você pode limitar a não diferenciação de maiúsculas e minúsculas apenas a partes de todo o padrão. Assim, a questão de onde colocá-lo realmente depende da especificação (embora para este problema específico isso não importe, pois não faz \wdistinção entre maiúsculas e minúsculas.

Para demonstrar, aqui está um exemplo semelhante de séries de letras em colapso como "AaAaaA"apenas "A".

    System.out.println(
        "AaAaaA eeEeeE IiiIi OoooOo uuUuUuu"
            .replaceAll("(?i)\\b([A-Z])\\1+\\b", "$1")
    ); // A e I O u

Agora, suponha que especificamos que a execução só deve ser recolhida se começar com uma letra maiúscula. Então, devemos colocar o (?i)no local apropriado:

    System.out.println(
        "AaAaaA eeEeeE IiiIi OoooOo uuUuUuu"
            .replaceAll("\\b([A-Z])(?i)\\1+\\b", "$1")
    ); // A eeEeeE I O uuUuUuu

De maneira mais geral, você pode ativar e desativar qualquer sinalizador dentro do padrão conforme desejar.

Veja também

Perguntas relacionadas

poligenelubrificantes
fonte
36

Se toda a sua expressão não diferencia maiúsculas de minúsculas, você pode apenas especificar o CASE_INSENSITIVEsinalizador:

Pattern.compile(regexp, Pattern.CASE_INSENSITIVE)
relet
fonte
Obrigado pela resposta. Isso é exatamente o que eu estava procurando. Em python, temos re.IGNORECASE estava procurando uma resposta semelhante em JAVA.
Doogle
0

Você também pode colocar sua string inicial, que vai verificar se há correspondência de padrões, em minúsculas. E use em seu padrão símbolos minúsculos, respectivamente.

Alexander Drobyshevsky
fonte