Czy w języku Java RegEx jest rozróżniana wielkość liter?

111

W Javie, wykonując replaceAll w celu wyszukania wzorca wyrażenia regularnego, takiego jak:

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

(aby usunąć zduplikowane kolejne słowa bez rozróżniania wielkości liter, np. test testowy), nie jestem pewien, gdzie umieściłem ?i. Czytałem, że ma to być na początku, ale jak to wyjmę to łapię zduplikowane kolejne słowa (np. Test testowy), ale nie bez rozróżniania wielkości liter (np. Test testowy). Więc pomyślałem, że mógłbym dodać? I na początku, ale nie wydaje się, aby to wykonało zadanie. jakieś pomysły? Dzięki!

Kryształ
źródło

Odpowiedzi:

119

RegexBuddy mówi mi, czy chcesz dołączyć go na początku, oto poprawna składnia:

"(?i)\\b(\\w+)\\b(\\s+\\1)+\\b"
cnanney
źródło
168

Możesz również dopasować wyrażenia regularne bez rozróżniania wielkości liter i uczynić je bardziej czytelnymi, używając stałej Pattern.CASE_INSENSITIVE, takiej jak:

Pattern mypattern = Pattern.compile(MYREGEX, Pattern.CASE_INSENSITIVE);
Matcher mymatcher= mypattern.matcher(mystring);
Christian Vielma
źródło
2
Mmmm .... bitowe operacje OR ...Pattern.compile(myregex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE)
Nick Grealy
4
To jest o wiele bardziej czytelne niż ta (?i)rzecz, wyrażenia regularne Java były już dość nieczytelne: S
Bartek Banachewicz
Jest to ta sama odpowiedź, co odpowiedź releta 4 lata wcześniej, ale otrzymała wszystkie głosy. Dziwny.
Zoomzoom
@Zoomzoom, to nie było, kiedy to pisałem :) Jeśli sprawdzisz historię wydania releta, zobaczysz, że zmieniła się na to w 2018 stackoverflow.com/posts/3436124/ ...
Christian Vielma
126

Tak, niewrażliwość na wielkość liter można dowolnie włączać i wyłączać w wyrażeniu regularnym Java.

Wygląda na to, że chcesz coś takiego:

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

Zauważ, że flaga osadzenia nie Pattern.CASE_INSENSITIVEjest . Zwróć także uwagę, że jeden zbędny został usunięty ze wzoru.(?i)\?i\b

Znak (?i)jest umieszczony na początku wzoru, aby umożliwić niewrażliwość na wielkość liter. W tym konkretnym przypadku nie jest on nadpisywany później we wzorcu, więc w efekcie w całym wzorcu nie jest rozróżniana wielkość liter.

Warto zauważyć, że w rzeczywistości można ograniczyć niewrażliwość na wielkość liter tylko do części całego wzoru. Zatem pytanie, gdzie to umieścić, tak naprawdę zależy od specyfikacji (chociaż w przypadku tego konkretnego problemu nie ma to znaczenia, ponieważ wielkość \wliter nie jest rozróżniana.

Aby zademonstrować, oto podobny przykład zwijania się ciągów liter, takich jak "AaAaaA"po prostu "A".

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

Załóżmy teraz, że określimy, że przebieg powinien być zwinięty tylko wtedy, gdy zaczyna się od dużej litery. Następnie musimy umieścić (?i)w odpowiednim miejscu:

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

Mówiąc bardziej ogólnie, możesz włączać i wyłączać dowolną flagę we wzorcu, jak chcesz.

Zobacz też

Powiązane pytania

smary wielogenowe
źródło
36

Jeśli całe wyrażenie nie uwzględnia wielkości liter, możesz po prostu określić CASE_INSENSITIVEflagę:

Pattern.compile(regexp, Pattern.CASE_INSENSITIVE)
ponownie
źródło
Dziękuję za odpowiedź. Dokładnie tego szukałem. W Pythonie re.IGNORECASE szukało podobnej odpowiedzi w JAVA.
Doogle
1

Możesz także doprowadzić swój początkowy ciąg, który zamierzasz sprawdzić pod kątem dopasowania do wzorca, do małych liter. I użyj odpowiednio małych liter w swoim wzorze.

Alexander Drobyshevsky
źródło