Ответы:
Начиная с Java 1.5, да :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
он вернется MicE
. Вы не ожидаете, что он вернется, MICE
потому что вы не подали заявку toUpperCase()
на ic
. В моем примере quote()
это также относится и к .*
вкладышу replaceAll()
. Вы должны сделать что-то еще, возможно .replaceAll("*","\\E.*\\Q")
, сработает, но это противоречит здравому смыслу.
*.wav
в шаблон регулярного выражения \*\.wav
, а replaceAll превратил бы его в \.*\.wav
, то есть файлы соответствия, имя которых состоит из произвольного числа периодов, за которыми следует .wav
. Скорее всего, вам бы понадобилось, replaceAll("\\*", ".*")
если бы они пошли с более хрупкой реализацией, которая основывается на распознавании всех возможных активных символов регулярных выражений и экранировании их по отдельности ... это было бы намного проще?
Разница между Pattern.quote
и Matcher.quoteReplacement
не была понятна мне до того, как я увидел следующий пример
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
заменяет специальные символы в строках поиска регулярных выражений, например. | + () И т. Д., И Matcher.quoteReplacement
заменяет специальные символы в строках замены, например \ 1 для обратных ссылок.
quoteReplacement
только заботами о двух символов $
и \
которые могут быть использованы , например , в замене строк в качестве обратных ссылок $1
или \1
. Поэтому его нельзя использовать для экранирования / цитирования регулярного выражения.
$Group$
с T$UYO$HI
. $
Символ является особенным , как в шаблоне и в замене:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Возможно, будет слишком поздно для ответа, но вы также можете использовать Pattern.LITERAL
, который будет игнорировать все специальные символы при форматировании:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Я думаю, что вы после этого \Q$5\E
. Также см. Pattern.quote(s)
Введено в Java5.
См. Шаблон Javadoc для деталей.
Во-первых, если
это не будет ставить 1 в конце. Он будет смотреть на регулярное выражение поиска для первой подходящей группы и подпункта THAT. Это означает, что $ 1, $ 2 или $ 3 означают в тексте замены: соответствующие группы из шаблона поиска.
Я часто вставляю длинные строки текста в файлы .properties, а затем генерирую из них темы и сообщения электронной почты. Действительно, это, кажется, способ сделать i18n по умолчанию в Spring Framework по умолчанию. Я помещаю теги XML в качестве заполнителей в строки и использую replaceAll () для замены тегов XML значениями во время выполнения.
Я столкнулся с проблемой, когда пользователь вводил цифру в долларах и центах со знаком доллара. replaceAll () захлебнулся, и в следовой строке появилось следующее:
java.lang.IndexOutOfBoundsException: No group 3
at java.util.regex.Matcher.start(Matcher.java:374)
at java.util.regex.Matcher.appendReplacement(Matcher.java:748)
at java.util.regex.Matcher.replaceAll(Matcher.java:823)
at java.lang.String.replaceAll(String.java:2201)
В этом случае пользователь ввел «$ 3» где-то в своем вводе, а replaceAll () пошёл искать в регулярном выражении поиска третью подходящую группу, не нашел ее и рванул.
Дано:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
замена
msg = msg.replaceAll("<userInput \\/>", userInput);
с участием
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
решил проблему. Пользователь может вводить любые символы, включая знаки доллара, без проблем. Он вел себя именно так, как вы ожидаете.
Чтобы иметь защищенный шаблон, вы можете заменить все символы на «\\\\», кроме цифр и букв. И после этого вы можете вставить в этот защищенный шаблон ваши специальные символы, чтобы этот шаблон работал не как глупый цитируемый текст, а как паттерн, но как ваш собственный. Без специальных символов пользователя.
public class Test {
public static void main(String[] args) {
String str = "y z (111)";
String p1 = "x x (111)";
String p2 = ".* .* \\(111\\)";
p1 = escapeRE(p1);
p1 = p1.replace("x", ".*");
System.out.println( p1 + "-->" + str.matches(p1) );
//.*\ .*\ \(111\)-->true
System.out.println( p2 + "-->" + str.matches(p2) );
//.* .* \(111\)-->true
}
public static String escapeRE(String str) {
//Pattern escaper = Pattern.compile("([^a-zA-z0-9])");
//return escaper.matcher(str).replaceAll("\\\\$1");
return str.replaceAll("([^a-zA-Z0-9])", "\\\\$1");
}
}
Pattern.quote ("Blabla") работает хорошо.
Pattern.quote () работает хорошо. Он включает в себя предложение с символами « \ Q » и « \ E », и, если он экранирует «\ Q» и «\ E». Однако, если вам нужно сделать реальное экранирование регулярного выражения (или пользовательское экранирование), вы можете использовать этот код:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Этот метод возвращает: Some / \ s / wText * / \, **
Код для примера и тесты:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Символ ^ (Отрицание) используется для сопоставления чего-либо, чего нет в группе символов.
Это ссылка на регулярные выражения
Вот информация об изображении об отрицании:
\Q
и\E
. Это может привести к неожиданным результатам, напримерPattern.quote("*.wav").replaceAll("*",".*")
, приведет к,\Q.*.wav\E
а не так.*\.wav
, как вы могли ожидать.