Является ли RegEx регистрозависимым?

В Java, когда выполняется replaceAll для поиска шаблона регулярного выражения, например:

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

(чтобы удалить дубликаты последовательных слов без учета регистра, например, Тестовый тест), я не уверен, куда я положил ?i. Я читал, что это должно быть в начале, но если я вычеркну его, то поймаю повторяющиеся слова подряд (например, тестовый тест), но не слова без учета регистра (например, тестовый тест). Поэтому я подумал, что мог бы добавить "я" в начале, но это, похоже, не делает работу. Какие-нибудь мысли? Спасибо!

Ответ 1

RegexBuddy сообщает мне, хотите ли вы включить его в начале, это правильный синтаксис:

"(?i)\\b(\\w+)\\b(\\s+\\1)+\\b"

Ответ 2

Вы также можете сопоставлять не зависящие от регистров регулярные выражения и сделать их более читаемыми с помощью константы Pattern.CASE_INSENSITIVE, например:

Pattern mypattern = Pattern.compile(MYREGEX, Pattern.CASE_INSENSITIVE);
Matcher mymatcher= mypattern.matcher(mystring);

Ответ 3

Да, нечувствительность к регистру может быть включена и отключена по желанию в Java regex.

Похоже, вы хотите что-то вроде этого:

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

Обратите внимание, что встроенный флаг Pattern.CASE_INSENSITIVE (?i) not \?i. Обратите внимание также, что один лишний \b был удален из шаблона.

(?i) помещается в начале шаблона, чтобы включить нечувствительность к регистру. В этом конкретном случае он не переопределяется позже в шаблоне, поэтому по сути весь шаблон нечувствителен к регистру.

Стоит отметить, что на самом деле вы можете ограничить нечувствительность к регистру только части всего шаблона. Таким образом, вопрос о том, где это сделать, действительно зависит от спецификации (хотя для этой конкретной задачи это не имеет значения, поскольку \w нечувствителен к регистру.

Чтобы продемонстрировать, здесь аналогичный пример сбрасывания прогонов букв, таких как "AaAaaA", только "A".

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

Теперь предположим, что мы указываем, что запуск должен быть свернут только в том случае, если он начинается с буквы верхнего регистра. Затем мы должны положить (?i) в нужное место:

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

В более общем плане вы можете включать и отключать любой флаг в шаблоне по своему усмотрению.

См. также

  • java.util.regex.Pattern
  • regular-expressions.info/Modifiers
    • Задание режимов внутри регулярного выражения
      • Вместо /regex/i (Pattern.CASE_INSENSITIVE в Java) вы можете сделать /(?i)regex/
    • Включение и выключение режимов поворота только для частичного выражения
      • Вы также можете сделать /first(?i)second(?-i)third/
    • Модификаторы
      • Вы также можете сделать /first(?i:second)third/
  • regular-expressions.info/Word Boundaries (всегда есть \b между \w и a \s)

Связанные вопросы

Ответ 4

Если все ваше выражение нечувствительно к регистру, вы можете просто указать флаг CASE_INSENSITIVE:

Pattern.compile(regexp, Pattern.CASE_INSENSITIVE)

Ответ 5

Вы также можете привести свою начальную строку, которую вы собираетесь проверить на соответствие шаблону, в нижний регистр. И используйте соответственно символы нижнего регистра шаблона.