Respostas:
Desde o Java 1.5, sim :
Pattern.quote("$5");
"mouse".toUpperCase().replaceAll("OUS","ic")
isso retornará MicE
. Você would't esperar que voltar MICE
porque você não se aplicava toUpperCase()
no ic
. No meu exemplo quote()
é aplicado no .*
insertet replaceAll()
também. Você tem que fazer outra coisa, talvez .replaceAll("*","\\E.*\\Q")
funcione, mas isso é contra-intuitivo.
*.wav
o padrão regex \*\.wav
e o replaceAll o transformaria \.*\.wav
, o que significa que seria corresponde aos arquivos cujo nome consiste em um número arbitrário de períodos seguidos por .wav
. Você provavelmente precisaria replaceAll("\\*", ".*")
se eles tivessem adotado a implementação mais frágil que depende do reconhecimento de todos os possíveis caracteres regex ativos e escapando deles individualmente ... isso seria muito mais fácil?
Diferença entre Pattern.quote
e Matcher.quoteReplacement
não estava clara para mim antes de ver o exemplo a seguir
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
Pattern.quote
substitui caracteres especiais em cadeias de caracteres de pesquisa de expressões regulares, como. | + () Etc, e Matcher.quoteReplacement
substitui caracteres especiais em cadeias de caracteres de substituição, como \ 1 para referências anteriores.
quoteReplacement
apenas se preocupa com os dois símbolos $
e \
que pode, por exemplo, ser usado em cadeias de substituição como referências posteriores $1
ou \1
. Portanto, não deve ser usado para escapar / citar um regex.
$Group$
com T$UYO$HI
. O $
símbolo é especial tanto no padrão como na substituição:"$Group$ Members".replaceFirst(Pattern.quote("$Group$"), Matcher.quoteReplacement("T$UYO$HI"))
Pode ser tarde demais para responder, mas você também pode usar Pattern.LITERAL
, o que ignoraria todos os caracteres especiais durante a formatação:
Pattern.compile(textToFormat, Pattern.LITERAL);
Pattern.CASE_INSENSITIVE
Eu acho que você está procurando \Q$5\E
. Veja também Pattern.quote(s)
introduzido no Java5.
Consulte javadoc padrão para obter detalhes.
Primeiro, se
não colocará 1 no final. Ele examinará o regex de pesquisa do primeiro grupo e sub-grupo correspondente. É isso que $ 1, $ 2 ou $ 3 significa no texto de substituição: grupos correspondentes do padrão de pesquisa.
Freqüentemente, plugue longas seqüências de texto em arquivos .properties e depois gero assuntos e corpos de email a partir deles. De fato, essa parece ser a maneira padrão de executar o i18n no Spring Framework. Coloco marcas XML, como espaços reservados, nas seqüências de caracteres e uso replaceAll () para substituir as marcas XML pelos valores em tempo de execução.
Encontrei um problema em que um usuário inseria uma figura de dólares e centavos, com um cifrão. replaceAll () engasgou, com o seguinte aparecendo em um stracktrace:
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)
Nesse caso, o usuário digitou "$ 3" em algum lugar da entrada e replaceAll () foi procurar no regex de pesquisa o terceiro grupo correspondente, não encontrou um e vomitou.
Dado:
// "msg" is a string from a .properties file, containing "<userInput />" among other tags
// "userInput" is a String containing the user's input
substituindo
msg = msg.replaceAll("<userInput \\/>", userInput);
com
msg = msg.replaceAll("<userInput \\/>", Matcher.quoteReplacement(userInput));
resolveu o problema. O usuário pode inserir qualquer tipo de caractere, incluindo cifrões, sem problemas. Ele se comportou exatamente da maneira que você esperaria.
Para ter um padrão protegido, você pode substituir todos os símbolos por "\\\\", exceto dígitos e letras. E depois disso, você pode colocar nesse padrão protegido seus símbolos especiais para fazer com que esse padrão funcione não como um texto citado estúpido, mas realmente como um padrão, mas o seu. Sem símbolos especiais do usuário.
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") funciona bem.
O Pattern.quote () funciona bem. Inclui a frase com os caracteres " \ Q " e " \ E " e, se escapar, "\ Q" e "\ E". No entanto, se você precisar fazer uma expressão regular real como escape (ou escape personalizado), poderá usar este código:
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
Este método retorna: Some / \ s / wText * / \, **
Código por exemplo e testes:
String someText = "Some\\E/s/wText*/,**";
System.out.println("Pattern.quote: "+ Pattern.quote(someText));
System.out.println("Full escape: "+someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
^ O símbolo (negação) é usado para corresponder a algo que não está no grupo de caracteres.
Este é o link para Expressões regulares
Aqui estão as informações da imagem sobre negação:
\Q
e\E
. Isso pode levar a resultados inesperados, por exemploPattern.quote("*.wav").replaceAll("*",".*")
, resultará\Q.*.wav\E
e não.*\.wav
, conforme o esperado.