[java] Java에서 정규식 텍스트를 이스케이프 처리하는 방법

Java에는 정규식에 포함될 수 있도록 임의의 텍스트를 이스케이프 처리하는 기본 제공 방법이 있습니까? 예를 들어 사용자가 “$ 5″를 입력하면 입력이 끝난 후 “5”가 아니라 정확하게 일치 시키려고합니다.



답변

이후 자바 1.5, 예 :

Pattern.quote("$5");


답변

다음 예를보기 전에 차이점 Pattern.quoteMatcher.quoteReplacement명확하지 않았습니다.

s.replaceFirst(Pattern.quote("text to replace"),
               Matcher.quoteReplacement("replacement text"));


답변

응답하기에는 너무 늦을 수도 있지만 Pattern.LITERAL형식을 지정하는 동안 모든 특수 문자를 무시하는 을 사용할 수도 있습니다 .

Pattern.compile(textToFormat, Pattern.LITERAL);


답변

당신이 쫓는 것은 \Q$5\E입니다. Pattern.quote(s)Java5에 도입 된 내용도 참조하십시오 .

세부 사항 은 패턴 javadoc을 참조하십시오.


답변

먼저

  • replaceAll ()을 사용합니다
  • Matcher.quoteReplacement ()를 사용하지 마십시오
  • 대체 될 텍스트는 $ 1을 포함합니다

끝에 1을 넣지 않습니다. 첫 번째 일치 그룹과 하위 THAT에 대한 검색 정규식을 살펴 봅니다. 대체 텍스트에서 $ 1, $ 2 또는 $ 3의 의미는 다음과 같습니다. 검색 패턴에서 일치하는 그룹.

긴 텍스트 문자열을 .properties 파일에 자주 연결 한 다음 전자 메일 제목과 본문을 생성합니다. 실제로 이것은 Spring Framework에서 i18n을 수행하는 기본 방법 인 것으로 보입니다. 자리 표시 자로 XML 태그를 문자열에 넣고 replaceAll ()을 사용하여 XML 태그를 런타임에 값으로 바꿉니다.

사용자가 달러 기호와 함께 달러와 센트 숫자를 입력하는 문제가 발생했습니다. replaceAll ()은 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)

이 경우 사용자가 입력에 어딘가에 “$ 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"));