자바는 임의의 텍스트를 이스케이프 처리하여 정규 표현식에 포함시킬 수 있습니까? 예를 들어 사용자가 "$ 5"를 입력하면 입력이 끝난 후 "5"가 아닌 정확히 일치 시키려합니다.자바에서 정규 표현식으로 텍스트를 이스케이프 처리하는 방법
답변
Java 1.5, yes 이후 :
Pattern.quote("$5");
나는 당신이 이후 \Q$5\E
하는지 생각합니다. Java5에서 소개 된 Pattern.quote(s)
도 참조하십시오.
자세한 내용은 Pattern javadoc을 참조하십시오. 내가 예를 들어 다음과 같은보기 전에 Pattern.quote
와 Matcher.quoteReplacement
사이
javadoc이 리터럴을 켜거나 끌 수있는 플래그가 없기 때문에 이것과 리터럴 플래그를 사용하는 데 차이가 있는지 궁금합니다. http : // java. sun.com/j2se/1.5.0/docs/api/java/util/regex/Pattern.html#LITERAL –
문자 그대로 \ Q와 \ E를 사용하는 것은 입력 내용을 알고있는 경우에만 유효합니다. Pattern.quote (s)는 텍스트에 실제로 이러한 시퀀스가 들어있는 경우도 처리합니다. –
차이가 나에게 분명하지 않다
s.replaceFirst(Pattern.quote("text to replace"),
Matcher.quoteReplacement("replacement text"));
특히'Pattern.quote'는. | +() 등의 정규식 검색 문자열의 특수 문자를 대체하며'Matcher.quoteReplacement'는 대체 문자열의 특수 문자를 대체합니다 (예 : 역 참조). – Steven
동의하지 않습니다. Pattern.quote는 인수를 \ Q 및 \ E로 래핑합니다. 특수 문자를 이스케이프 처리하지 않습니다. –
Matcher.quoteReplacement ("4 $ & % $")는 "4 \ $ & % \ $"를 생성합니다. 특수 문자를 이스케이프 처리합니다. –
우선 해제, 당신은 완전히 대체하기()를 사용
- 경우
- 당신이 Matcher를 사용하지 마십시오 .quoteReplacement()
- 대체 할 텍스트에는 $ 1이 포함됩니다.
끝 부분에 1을 넣지 않습니다. 첫 번째 일치하는 그룹에 대한 검색 정규 표현식과 THAT에있는 sub를 살펴볼 것입니다. 대체 텍스트에서 $ 1, $ 2 또는 $ 3은 검색 패턴의 일치 그룹을 의미합니다.
자주 긴 텍스트 문자열을 .properties 파일에 연결 한 다음 전자 메일 제목과 본문을 생성합니다. 실제로 이것은 Spring Framework에서 i18n을 수행하는 기본 방법 인 것으로 보입니다. 자리 표시 자로 XML 태그를 문자열에 넣고 replaceAll()을 사용하여 런타임시 XML 태그를 값으로 대체합니다.
사용자가 달러 기호를 사용하여 달러와 센트 수치를 입력하는 문제가 발생했습니다. 에 대한 검색 정규식에서 찾고
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"을 입력 한 갔다 : 완전히 대체하기()는 다음이 stracktrace에 표시와 함께, 거기에 숨 막혀 세 번째 매칭 그룹, 하나를 찾지 못했습니다.
주어 :
// "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 \\/>", Matcher.quoteReplacement(userInput));
으로
msg = msg.replaceAll("<userInput \\/>", userInput);
교체 문제를 해결했다. 사용자는 아무런 문제없이 달러 기호를 포함한 모든 종류의 문자를 넣을 수 있습니다. 그것은 당신이 기대했던 것과 똑같이 행동했습니다.
보호 된 패턴을 사용하려면 숫자와 문자를 제외한 모든 기호를 "\\\\"로 바꿀 수 있습니다. 그 후에 보호 된 패턴에 특수 기호를 넣으면이 패턴이 멍청한 따옴표로 묶인 텍스트가 아닌 patten과 같게 만들 수 있습니다. 사용자 특수 기호없이.
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");
}
}
공백을 벗어날 필요가 없습니다. 따라서 패턴을 "([^ a-zA-z0-9])"로 변경할 수 있습니다. –
작은 오타, 큰 결과 : "([^ a-zA-z0-9])"도 일치하지 않습니다 (즉, 탈출하지 않음) [, \,],^확실히 탈출하고 싶습니다! 오타는 'Z'여야하는 두 번째 'z'입니다. 그렇지 않으면 ASCII 65에서 ASCII 122까지의 모든 문자가 포함됩니다. – Zefiro
응답하는 데 시간이 너무 늦을 수 있지만, 당신은 또한 포맷하는 동안 모든 특수 문자를 무시 것이다, Pattern.LITERAL
를 사용할 수 있습니다
Pattern.compile(textToFormat, Pattern.LITERAL);
'Pattern.CASE_INSENSITIVE'와 결합 할 수있어 특히 좋습니다. – mjjaniec
Pattern.quote ("blabla")는 잘 작동합니다.
Pattern.quote()는 잘 작동합니다. "\ Q"및 "\ E"의 문장을 포함하고 "\ Q"및 "\ E"를 이스케이프하면 문장을 둘러 쌉니다.
String someText = "Some/s/wText*/,**";
System.out.println(someText.replaceAll("[-\\[\\]{}()*+?.,\\\\\\\\^$|#\\\\s]", "\\\\$0"));
이 메소드가 리턴 : 일부/\ 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'를 사용하십시오. – Paramaeleon
@Paramaeleon 왜 foo (x) .bar() == x.bar()입니까? – Michael
@Paramaeleon 유스 케이스를 오해하고 있다고 생각합니다. – vikingsteve