Java Language
정규 표현식
수색…
소개
정규 표현식은 특수한 패턴의 문자열을 사용하여 다른 문자열이나 문자열 집합을 찾거나 찾는 데 도움이되는 특수 문자 시퀀스입니다. Java는 java.util.regex
패키지를 통해 정규 표현식 사용을 지원합니다. 이 주제는 Java에서 정규 표현식을 사용해야하는 방법에 대한 예제를 개발자가 이해하고 이해하도록 돕는 것입니다.
통사론
- 패턴 patternName = Pattern.compile (정규식);
- Matcher matcherName = patternName.matcher (textToSearch);
- matcherName.matches () // textToSearch가 정규 표현식과 정확히 일치하면 true를 반환합니다.
- matcherName.find () // textToSearch를 통해 정규 표현식과 일치하는 부분 문자열의 첫 번째 인스턴스를 검색합니다. 후속 호출은 문자열의 나머지 부분을 검색합니다.
- matcherName.group (groupNum) // 캡처 링 그룹 내부에서 부분 문자열을 반환합니다.
- matcherName.group (groupName) // 명명 된 캡처 그룹 (Java 7 이상)의 하위 문자열을 반환합니다.
비고
수입품
Regex를 사용하려면 먼저 다음 가져 오기를 추가해야합니다.
import java.util.regex.Matcher
import java.util.regex.Pattern
함정
자바에서는 백 슬래시가 이중 백 슬래시로 이스케이프 처리되므로 정규식 문자열의 백 슬래시는 이중 백 슬래시로 입력해야합니다. 단일 백 슬래시와 정규식을 일치 시키려면 이중 백 슬래시를 이스케이프해야합니다. 백 슬래시를 네 개 백 슬래시로 입력해야합니다.
중요한 기호 설명
캐릭터 | 기술 |
---|---|
* | 앞의 문자 또는 하위 표현식을 0 번 이상 일치시킵니다. |
+ | 앞의 문자 또는 하위 표현식을 1 회 이상 일치시킵니다. |
? | 앞의 문자 또는 하위 표현식을 0 번 또는 1 번 일치시킵니다. |
추가 읽기
regex 항목 에는 정규 표현식에 대한 자세한 정보가 들어 있습니다.
캡처 그룹 사용
입력 문자열에서 문자열의 일부를 추출해야하는 경우 regex의 캡처 그룹 을 사용할 수 있습니다.
이 예제에서는 간단한 전화 번호 정규식으로 시작합니다.
\d{3}-\d{3}-\d{4}
괄호가 정규식에 추가되면 각 괄호 세트는 캡처 그룹으로 간주됩니다. 이 경우 번호가 지정된 캡처 그룹을 사용하고 있습니다.
(\d{3})-(\d{3})-(\d{4})
^-----^ ^-----^ ^-----^
Group 1 Group 2 Group 3
Java에서 사용할 수 있기 전에 문자열의 규칙을 따르는 것을 잊지 말고 백 슬래시를 이스케이프하여 다음과 같은 패턴을 만듭니다.
"(\\d{3})-(\\d{3})-(\\d{4})"
우리는 먼저 확인하기 위해 정규식 패턴을 컴파일 할 필요가 Pattern
한 후 우리는 필요 Matcher
패턴과 우리의 입력 문자열을 일치 :
Pattern phonePattern = Pattern.compile("(\\d{3})-(\\d{3})-(\\d{4})");
Matcher phoneMatcher = phonePattern.matcher("abcd800-555-1234wxyz");
다음으로, Matcher는 정규식과 일치하는 첫 번째 서브 시퀀스를 찾아야합니다.
phoneMatcher.find();
이제 그룹 메소드를 사용하여 문자열에서 데이터를 추출 할 수 있습니다.
String number = phoneMatcher.group(0); //"800-555-1234" (Group 0 is everything the regex matched)
String aCode = phoneMatcher.group(1); //"800"
String threeDigit = phoneMatcher.group(2); //"555"
String fourDigit = phoneMatcher.group(3); //"1234"
참고 : Matcher.group()
Matcher.group(0)
대신 Matcher.group()
사용할 수 있습니다.
Java 7은 명명 된 캡처 그룹을 도입했습니다. 명명 된 캡처 그룹은 약간의 구문 변경이 있지만 번호가 지정된 캡처 그룹과 동일하지만 (숫자 대신 이름이 있음) 기능합니다. 명명 된 캡처 그룹을 사용하면 가독성이 향상됩니다.
위의 코드를 명명 된 그룹을 사용하도록 변경할 수 있습니다.
(?<AreaCode>\d{3})-(\d{3})-(\d{4})
^----------------^ ^-----^ ^-----^
AreaCode Group 2 Group 3
"AreaCode"의 내용을 얻으려면 대신 다음을 사용할 수 있습니다.
String aCode = phoneMatcher.group("AreaCode"); //"800"
패턴을 플래그로 컴파일하여 사용자 정의 비헤이비어로 정규 표현식 사용
Pattern
을 플래그로 컴파일 할 수 있습니다. 정규 표현식을 리터럴 String
로 사용하는 경우 인라인 수정자를 사용하십시오.
Pattern pattern = Pattern.compile("foo.", Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
pattern.matcher("FOO\n").matches(); // Is true.
/* Had the regex not been compiled case insensitively and singlelined,
* it would fail because FOO does not match /foo/ and \n (newline)
* does not match /./.
*/
Pattern anotherPattern = Pattern.compile("(?si)foo");
anotherPattern.matcher("FOO\n").matches(); // Is true.
"foOt".replaceAll("(?si)foo", "ca"); // Returns "cat".
이스케이프 문자
일반적으로
리터럴 의미에서 정규 표현식 특정 문자 ( ?+|
등)를 사용하려면 이스케이프해야합니다. 일반적인 정규 표현식에서 이것은 백 슬래시 \
의해 수행됩니다. 그러나 Java Strings에서 특별한 의미가 있으므로 이중 백 슬래시 \\
를 사용해야합니다.
다음 두 예제는 작동하지 않습니다.
"???".replaceAll ("?", "!"); //java.util.regex.PatternSyntaxException
"???".replaceAll ("\?", "!"); //Invalid escape sequence
이 예제는 작동한다.
"???".replaceAll ("\\?", "!"); //"!!!"
파이프 구분 문자열 분리
예상 된 결과를 반환하지 않습니다.
"a|b".split ("|"); // [a, |, b]
예상 된 결과를 반환합니다.
"a|b".split ("\\|"); // [a, b]
역 슬래시 이스케이프 \
이렇게하면 오류가 발생합니다.
"\\".matches("\\"); // PatternSyntaxException
"\\".matches("\\\"); // Syntax Error
작동 방식 :
"\\".matches("\\\\"); // true
정규식 리터럴과 일치.
정규 표현식 구문의 일부인 문자를 일치시켜야하는 경우 패턴의 전체 또는 일부를 정규식 리터럴로 표시 할 수 있습니다.
\Q
는 정규 표현식의 시작을 표시합니다. \E
는 정규 표현식의 끝을 표시합니다.
// the following throws a PatternSyntaxException because of the un-closed bracket
"[123".matches("[123");
// wrapping the bracket in \Q and \E allows the pattern to match as you would expect.
"[123".matches("\\Q[\\E123"); // returns true
\Q
및 \E
이스케이프 시퀀스를 기억하지 않고도 쉽게 수행 할 수있는 방법은 Pattern.quote()
를 사용하는 것입니다.
"[123".matches(Pattern.quote("[") + "123"); // returns true
주어진 문자열과 일치하지 않음
주어진 문자열을 포함하지 않는 것을 일치 시키려면 부정적인 lookahead를 사용할 수 있습니다 :
정규식 구문 : (?!string-to-not-match)
예:
//not matching "popcorn"
String regexString = "^(?!popcorn).*$";
System.out.println("[popcorn] " + ("popcorn".matches(regexString) ? "matched!" : "nope!"));
System.out.println("[unicorn] " + ("unicorn".matches(regexString) ? "matched!" : "nope!"));
산출:
[popcorn] nope!
[unicorn] matched!
백 슬래시 일치시키기
정규식에서 백 슬래시와 일치 시키려면 이스케이프 처리해야합니다.
백 슬래시는 정규식에서 이스케이프 문자입니다. '\\'를 사용하여 정규 표현식에서 단일 백 슬래시를 나타낼 수 있습니다.
그러나 백 슬래시는 Java 리터럴 문자열의 이스케이프 문자 이기도 합니다. 문자열에서 정규 표현식 리터럴하려면, 당신은 백 슬래시의 각을 탈출해야합니다. 문자열 리터럴에서 '\\\\'는 '\\'을 가진 정규 표현식을 만드는 데 사용할 수 있으며 '\\'와 일치 할 수 있습니다.
예를 들어 "C : \ dir \ myfile.txt"와 같은 문자열을 찾습니다. 정규식 ([A-Za-z]):\\(.*)
이 일치하고 드라이브 문자를 캡처 그룹으로 제공합니다. 이중 백 슬래시에 유의하십시오.
자바 문자열 리터럴에서 그 패턴을 표현하기 위해 정규 표현식에서 각 백 슬래시를 이스케이프 처리해야합니다.
String path = "C:\\dir\\myfile.txt";
System.out.println( "Local path: " + path ); // "C:\dir\myfile.txt"
String regex = "([A-Za-z]):\\\\.*"; // Four to match one
System.out.println("Regex: " + regex ); // "([A-Za-z]):\\(.*)"
Pattern pattern = Pattern.compile( regex );
Matcher matcher = pattern.matcher( path );
if ( matcher.matches()) {
System.out.println( "This path is on drive " + matcher.group( 1 ) + ":.");
// This path is on drive C:.
}
두 개의 백 슬래시를 일치시키려는 경우 리터럴 문자열에서 8을 사용하여 정규 표현식에서 4를 나타내는 2를 찾습니다.
String path = "\\\\myhost\\share\\myfile.txt";
System.out.println( "UNC path: " + path ); // \\myhost\share\myfile.txt"
String regex = "\\\\\\\\(.+?)\\\\(.*)"; // Eight to match two
System.out.println("Regex: " + regex ); // \\\\(.+?)\\(.*)
Pattern pattern = Pattern.compile( regex );
Matcher matcher = pattern.matcher( path );
if ( matcher.matches()) {
System.out.println( "This path is on host '" + matcher.group( 1 ) + "'.");
// This path is on host 'myhost'.
}