регулярное выражение заменяет все игнорируемые регистры

#java #regex

#java #регулярное выражение

Вопрос:

Как мне игнорировать регистр в приведенном ниже примере?

 outText = inText.replaceAll(word, word.replaceAll(" ", "~"));
  

Пример:

Ввод:

 inText = "Retail banking Wikipedia, the free encyclopedia Retail banking "
         "From Wikipedia. retail banking industry."

word   = "retail banking"
  

Вывод

 outText = "Retail~banking Wikipedia, the free encyclopedia Retail~banking "  
          "From Wikipedia. retail~banking industry."
  

Комментарии:

1. Я не понимаю, почему регистр является проблемой при замене пробелов.

2. о, потому что пробел должен быть между определенными совпадениями без учета регистра. Если в вашем языке нет опции icase, обратные ссылки могут это сделать.

Ответ №1:

Чтобы выполнить поиск и замену без учета регистра, вы можете изменить

 outText = inText.replaceAll(word, word.replaceAll(" ", "~"));
  

в

 outText = inText.replaceAll("(?i)"   word, word.replaceAll(" ", "~"));
  

Избегайте искажения первоначальной заглавной буквы:

Однако в приведенном выше подходе вы нарушаете заглавную букву заменяемого слова. Вот лучшее предложение:

 String inText="Sony Ericsson is a leading company in mobile. "  
              "The company sony ericsson was found in oct 2001";
String word = "sony ericsson";

Pattern p = Pattern.compile(word, Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(inText);

StringBuffer sb = new StringBuffer();

while (m.find()) {
  String replacement = m.group().replace(' ', '~');
  m.appendReplacement(sb, Matcher.quoteReplacement(replacement));
}
m.appendTail(sb);

String outText = sb.toString();

System.out.println(outText);
  

Вывод:

 Sony~Ericsson is a leading company in mobile.
The company sony~ericsson was found in oct 2001
  

Комментарии:

1. Обратите внимание, что без флага UNICODE_CASE or (?u) вы не получите правильного преобразования в регистр Юникода. Это не имеет значения для чисто ASCII-данных, но будет иметь значение, если у вас есть не-ASCII-прописные буквы, включая только латинские, такие как римские цифры, like king henry ⅷ и King Henry Ⅷ , которые являются вариантами регистра друг друга. Простой нелатинский пример заключается в том, что ΣΤΙΓΜΑΣ , στιγμας и στιγμασ должны совпадать друг с другом без учета регистра, потому что греческая сигма имеет три разные формы. (И да, я знаю, что множественное число στιγμα действительно στιγματα . 🙂

2. @tchrist вы предлагаете заменить «(?i) [..]» на «(?ui) [..]»? Это то, что сработало для меня.

3. @k3b Да, это то, что я имел в виду.

4. @tchrist ты просто экономишь мое время, спасибо! Странно, что по умолчанию форматирование в юникоде не работает «из коробки»

Ответ №2:

Вы могли бы преобразовать все это в нижний регистр перед выполнением поиска или посмотреть на шаблон модификатора regex.CASE_INSENSITIVE

Ответ №3:

Вот мой способ сделать это:

         private String replaceAllIgnoreCase(final String text, final String search, final String replacement){
        if(search.equals(replacement)) return text;
        final StringBuffer buffer = new StringBuffer(text);
        final String lowerSearch = search.toLowerCase(Locale.CANADA);
        int i = 0;
        int prev = 0;
        while((i = buffer.toString().toLowerCase(Locale.CANADA).indexOf(lowerSearch, prev)) > -1){
            buffer.replace(i, i search.length(), replacement);
            prev = i replacement.length();
        }
        return buffer.toString();
    }
  

Кажется, работает безупречно в моей степени. Хорошая вещь в том, что я делаю это по-своему, заключается в том, что в моем решении нет регулярных выражений, то есть, если вы хотите заменить скобку или знак плюс (или любой другой мета-символ, если уж на то пошло), это фактически заменит текст таким, какой он есть на самом деле, а не тем, что он означает в regex. Надеюсь, это помогло.

Ответ №4:

Вы не указали язык.

Java имеет шаблон.CASE_INSENSITIVE

C # и VB имеют варианты регулярных выражений.Игнорируемый регистр