Відповіді:
Оскільки Java 1.5 так :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
це зробите , повернетесь MicE
. Ви would't очікувати , що вона повернеться , MICE
тому що ви не застосовувати toUpperCase()
на ic
. У моєму прикладі quote()
також застосовано до .*
вставки replaceAll()
. Вам доведеться робити щось інше, можливо .replaceAll("*","\\E.*\\Q")
, спрацювало б, але це контрінтуїтивно.
*.wav
на схему регулярних \*\.wav
виразів, а замінуAll перетворило б його в \.*\.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.
Докладніше див. Шаблон Явадок.
По-перше, якщо
він не поставить 1 в кінці. Він буде розглядати конвеєр пошуку для першої групи, що відповідає, та суб ТО. Це те, що означає $ 1, $ 2 або $ 3 у тексті заміни: відповідність груп за схемою пошуку.
Я часто підключаю довгі рядки тексту до файлів .properties, а потім генерую з них предмети та тіла електронної пошти. Дійсно, це є типовим способом зробити i18n у Spring Framework. Я поміщаю теги XML, як заповнювачі, у рядки, і використовую substituAll () для заміни тегів XML зі значеннями під час виконання.
Я зіткнувся з проблемою, коли користувач вводить цифру доларів і центів зі знаком долара. substituAll (), що його захлинулося, із слідом відображення:
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" десь у своєму введенні та заміниAll () пішов шукати регекс для третьої групи, що відповідає, не знайшов його, і забрав.
Подано:
// "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 ("блабла") працює добре.
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
, як ви могли очікувати.