#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-прописные буквы, включая только латинские, такие как римские цифры, likeking 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 имеют варианты регулярных выражений.Игнорируемый регистр