
정규식(regex)이란 무엇입니까?
사실 정규 표현식은 텍스트에서 문자열을 찾기 위한 패턴입니다. Java에서 이 패턴의 원래 표현은 항상 문자열, 즉 클래스의 객체입니다String
. 그러나 정규식으로 컴파일할 수 있는 문자열은 아닙니다. 정규식 생성 규칙을 준수하는 문자열만 가능합니다. 구문은 언어 사양에 정의되어 있습니다. 정규식은 정규식 구문에서 특별한 의미를 갖는 문자인 메타문자뿐만 아니라 문자와 숫자를 사용하여 작성됩니다. 예를 들어:
String regex = "java"; // The pattern is "java";
String regex = "\\d{3}"; // The pattern is three digits;
Java에서 정규식 만들기
Java에서 정규식을 작성하려면 두 가지 간단한 단계가 필요합니다.- 정규식 구문을 준수하는 문자열로 작성하십시오.
- 문자열을 정규식으로 컴파일합니다.
Pattern
. 이렇게 하려면 클래스의 두 가지 정적 메서드 중 하나를 호출해야 합니다 compile
. 첫 번째 메서드는 정규식을 포함하는 문자열 리터럴인 하나의 인수를 사용하고 두 번째 메서드는 패턴 일치 설정을 결정하는 추가 인수를 사용합니다.
public static Pattern compile (String literal)
public static Pattern compile (String literal, int flags)
매개변수 의 잠재적 값 목록은 클래스 flags
에서 정의되며 Pattern
정적 클래스 변수로 사용할 수 있습니다. 예를 들어:
Pattern pattern = Pattern.compile("java", Pattern.CASE_INSENSITIVE); // Pattern-matching will be case insensitive.
기본적으로 Pattern
클래스는 정규 표현식의 생성자입니다. 내부적으로 이 compile
메서드는 클래스의 전용 생성자를 호출하여 Pattern
컴파일된 표현을 만듭니다. 이 객체 생성 메커니즘은 불변 객체를 생성하기 위해 이러한 방식으로 구현됩니다. 정규식이 생성되면 구문이 검사됩니다. 문자열에 오류가 있으면 a가 PatternSyntaxException
생성됩니다.
정규 표현식 구문
<([{\^-=$!|]})?*+.>
정규 표현식 구문은 문자와 결합될 수 있는 문자 에 의존합니다 . 역할에 따라 여러 그룹으로 나눌 수 있습니다.
메타문자 | 설명 |
---|---|
^^ | 줄의 시작 |
$ | 줄의 끝 |
\비 | 단어 경계 |
\비 | 비단어 경계 |
\ㅏ | 입력의 시작 |
\G | 이전 경기 종료 |
\지 | 입력의 끝 |
\지 | 입력의 끝 |
메타문자 | 설명 |
---|---|
\디 | 숫자 |
\디 | 숫자가 아닌 |
\에스 | 공백 문자 |
\에스 | 공백이 아닌 문자 |
\w | 영숫자 문자 또는 밑줄 |
\W | 문자, 숫자 및 밑줄을 제외한 모든 문자 |
. | 모든 문자 |
메타문자 | 설명 |
---|---|
\티 | 탭 문자 |
\N | 개행 문자 |
\아르 자형 | 캐리지 리턴 |
\에프 | 줄 바꿈 문자 |
\u0085 | 다음 줄 문자 |
\u2028 | 줄 구분 기호 |
\u2029 | 단락 구분자 |
메타문자 | 설명 |
---|---|
[알파벳] | 나열된 문자(a, b 또는 c) |
[^abc] | 나열된 것 이외의 모든 문자(a, b 또는 c 제외) |
[a-zA-Z] | 병합된 범위(a에서 z까지의 라틴 문자, 대소문자 구분 안 함) |
[광고[mp]] | 문자의 합집합(a에서 d까지, m에서 p까지) |
[az&&[데프]] | 문자의 교차점(d, e, f) |
[az&&[^bc]] | 문자 빼기(a, dz) |
메타문자 | 설명 |
---|---|
? | 하나 또는 없음 |
* | 0회 이상 |
+ | 한 번 이상 |
{N} | n번 |
{N,} | n회 이상 |
{n,m} | n회 이상 m회 이하 |
탐욕스러운 수량자
수량사에 대해 알아야 할 한 가지는 탐욕적, 소유적, 꺼려하는 세 가지 종류가 있다는 것입니다.+
한정사 뒤에 " " 문자를 추가하여 수량사를 소유격으로 만듭니다 . " "를 추가하여 주저하게 만듭니다 ?
. 예를 들어:
"A.+a" // greedy
"A.++a" // possessive
"A.+?a" // reluctant
이 패턴을 사용하여 다양한 유형의 한정 기호가 작동하는 방식을 이해해 봅시다. 기본적으로 수량자는 탐욕적입니다. 즉, 문자열에서 가장 긴 일치 항목을 찾습니다. 다음 코드를 실행하면:
public static void main(String[] args) {
String text = "Fred Anna Alexander";
Pattern pattern = Pattern.compile("A.+a");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
System.out.println(text.substring(matcher.start(), matcher.end()));
}
}
이 출력을 얻습니다.
Anna Alexa
정규식 " A.+a
"의 경우 패턴 일치는 다음과 같이 수행됩니다.
-
지정된 패턴의 첫 번째 문자는 라틴 문자입니다
A
.Matcher
인덱스 0부터 시작하여 텍스트의 각 문자와 비교합니다. 문자는F
텍스트에서 인덱스 0에 있으므로Matcher
패턴과 일치할 때까지 문자를 반복합니다. 이 예에서 이 문자는 인덱스 5에서 찾을 수 있습니다. -
패턴의 첫 번째 문자와 일치하는 항목이 발견되면
Matcher
두 번째 문자와 일치하는 항목을 찾습니다..
우리의 경우에는 모든 문자를 나타내는 " " 문자입니다 .캐릭터는
n
여섯 번째 위치에 있습니다. 확실히 "모든 문자"와 일치하는 자격이 있습니다. -
Matcher
패턴의 다음 문자를 확인합니다. 우리의 패턴에서는 선행 문자 " "에 적용되는 한정사에 포함됩니다.+
. 패턴에서 "모든 문자"의 반복 횟수가 1회 이상이므로Matcher
"모든 문자"와 일치하는 한 문자열에서 다음 문자를 반복적으로 가져와 패턴에 대해 확인합니다. 이 예에서 — 문자열 끝까지(인덱스 7에서 인덱스 18까지).기본적으로
Matcher
문자열을 끝까지 먹습니다. 이것이 바로 "탐욕스러운"의 의미입니다. -
Matcher는 텍스트 끝에 도달하고 패턴의 " " 부분에 대한 확인을 마친 후
A.+
패턴의 나머지 부분에 대한 확인을 시작합니다.a
. 앞으로 더 이상 텍스트가 없으므로 검사는 마지막 문자부터 시작하여 "백오프"로 진행됩니다. -
Matcher
.+
패턴의 " " 부분에서 반복 횟수를 "기억"합니다 . 이 시점에서 반복 횟수를 하나씩 줄이고 일치하는 항목을 찾을 때까지 텍스트에 대해 더 큰 패턴을 확인합니다.
소유 수량사
소유 수량자는 탐욕스러운 것과 매우 비슷합니다. 차이점은 텍스트가 문자열 끝까지 캡처된 경우 "백오프"하는 동안 패턴 일치가 없다는 것입니다. 즉, 처음 세 단계는 탐욕 수량자와 동일합니다. 전체 문자열을 캡처한 후 매처는 고려 중인 패턴에 나머지 패턴을 추가하고 캡처된 문자열과 비교합니다. 이 예에서 정규식 "A.++a
"을 사용하면 기본 메서드가 일치하는 항목을 찾지 않습니다. 
꺼려하는 수량사
-
탐욕적 다양성과 마찬가지로 이러한 수량자의 경우 코드는 패턴의 첫 번째 문자를 기반으로 일치 항목을 찾습니다.
-
그런 다음 패턴의 다음 문자(모든 문자)와 일치하는 항목을 찾습니다.
-
그리디 패턴매칭과 달리 마지못한 패턴매칭에서는 최단 일치를 찾는다. 즉, 패턴의 두 번째 문자(텍스트에서 위치 6에 있는 문자에 해당하는 마침표)와 일치하는 항목을 찾은 후
Matcher
텍스트가 패턴의 나머지 부분인 "a
" 문자와 일치하는지 확인합니다. -
n
텍스트가 패턴과 일치하지 않으므로(즉 , 인덱스 7에 " " 문자 포함 )Matcher
한정 기호가 하나 이상을 나타내므로 "모든 문자"를 하나 더 추가합니다. 그런 다음 패턴을 위치 5에서 8까지의 텍스트와 다시 비교합니다.
우리의 경우 일치하는 항목이 있지만 아직 텍스트 끝에 도달하지 않았습니다. 따라서 패턴 일치는 위치 9부터 다시 시작됩니다. 즉, 유사한 알고리즘을 사용하여 패턴의 첫 번째 문자를 찾고 이것은 텍스트가 끝날 때까지 반복됩니다.

main
방법은 " " 패턴을 사용할 때 다음과 같은 결과를 얻습니다 A.+?a
. Anna Alexa 우리의 예에서 볼 수 있듯이 다른 유형의 수량어는 동일한 패턴에 대해 다른 결과를 생성합니다. 따라서 이것을 염두에 두고 찾고 있는 것에 따라 올바른 품종을 선택하십시오.
정규 표현식의 이스케이프 문자
Java의 정규식 또는 원래 표현은 문자열 리터럴이기 때문에 문자열 리터럴에 관한 Java 규칙을 고려해야 합니다. 특히\
Java 소스 코드에서 문자열 리터럴의 백슬래시 문자 " "는 컴파일러에게 다음 문자가 특별하고 특별한 방식으로 해석되어야 함을 알리는 제어 문자로 해석됩니다. 예를 들어:
String s = "The root directory is \nWindows"; // Move "Windows" to a new line
String s = "The root directory is \u00A7Windows"; // Insert a paragraph symbol before "Windows"
즉, 정규식을 설명하고 " \
" 문자(예: 메타문자를 나타냄)를 사용하는 문자열 리터럴은 백슬래시를 반복하여 Java 바이트코드 컴파일러가 문자열을 잘못 해석하지 않도록 해야 합니다. 예를 들어:
String regex = "\\s"; // Pattern for matching a whitespace character
String regex = "\"Windows\""; // Pattern for matching "Windows"
"일반" 문자로 사용하려는 특수 문자를 이스케이프하려면 이중 백슬래시를 사용해야 합니다. 예를 들어:
String regex = "How\\?"; // Pattern for matching "How?"
패턴 클래스의 메서드
이Pattern
클래스에는 정규 표현식으로 작업하기 위한 다른 메서드가 있습니다.
-
String pattern()
‒ 객체를 생성하는 데 사용된 정규식의 원래 문자열 표현을 반환합니다Pattern
.Pattern pattern = Pattern.compile("abc"); System.out.println(pattern.pattern()); // "abc"
-
static boolean matches(String regex, CharSequence input)
– 로 전달된 텍스트에 대해 regex로 전달된 정규식을 확인할 수 있습니다input
. 보고:true – 텍스트가 패턴과 일치하는 경우;
false – 그렇지 않은 경우;예를 들어:
System.out.println(Pattern.matches("A.+a","Anna")); // true System.out.println(Pattern.matches("A.+a","Fred Anna Alexander")); // false
-
int flags()
‒ 패턴이 생성되었을 때 설정된 패턴의 매개변수 값을 반환하거나flags
매개변수가 설정되지 않은 경우 0을 반환합니다. 예를 들어:Pattern pattern = Pattern.compile("abc"); System.out.println(pattern.flags()); // 0 Pattern pattern = Pattern.compile("abc",Pattern.CASE_INSENSITIVE); System.out.println(pattern.flags()); // 2
-
String[] split(CharSequence text, int limit)
– 전달된 텍스트를 배열로 분할합니다String
. 이limit
매개변수는 텍스트에서 검색된 최대 일치 수를 나타냅니다.- if
limit > 0
-limit-1
일치하는 경우; - if
limit < 0
‒ 텍스트의 모든 일치 항목 - ‒ 텍스트의 모든 일치 항목 인 경우
limit = 0
배열 끝에 있는 빈 문자열은 버려집니다.
예를 들어:
public static void main(String[] args) { String text = "Fred Anna Alexa"; Pattern pattern = Pattern.compile("\\s"); String[] strings = pattern.split(text,2); for (String s : strings) { System.out.println(s); } System.out.println("---------"); String[] strings1 = pattern.split(text); for (String s : strings1) { System.out.println(s); } }
콘솔 출력:
Fred Anna Alexa --------- Fred Anna Alexa
아래에서는 개체를 만드는 데 사용되는 클래스의 다른 메서드를 살펴보겠습니다
Matcher
. - if
Matcher 클래스의 메서드
패턴 일치를 수행하기 위해 클래스 의 인스턴스가Matcher
생성됩니다. Matcher
정규 표현식의 "검색 엔진"입니다. 검색을 수행하려면 패턴과 시작 인덱스라는 두 가지 항목을 제공해야 합니다. Matcher
개체를 만들기 위해 Pattern
클래스는 다음 메서드를 제공합니다. рublic Matcher matcher(CharSequence input)
이 메서드는 검색할 문자 시퀀스를 사용합니다. 인터페이스 를 구현하는 클래스의 인스턴스입니다 CharSequence
. String
a 뿐만 아니라 StringBuffer
, StringBuilder
, Segment
또는 를 전달할 수도 있습니다 CharBuffer
. 패턴은 메소드가 호출 Pattern
되는 객체 입니다 matcher
. 매처 생성의 예:
Pattern p = Pattern.compile("a*b"); // Create a compiled representation of the regular expression
Matcher m = p.matcher("aaaaab"); // Create a "search engine" to search the text "aaaaab" for the pattern "a*b"
이제 "검색 엔진"을 사용하여 일치 항목을 검색하고, 텍스트에서 일치 항목의 위치를 가져오고, 클래스의 메서드를 사용하여 텍스트를 바꿀 수 있습니다. 메서드는 boolean find()
텍스트에서 다음 일치 항목을 찾습니다. 이 메서드와 루프 문을 사용하여 전체 텍스트를 이벤트 모델의 일부로 분석할 수 있습니다. 즉, 이벤트가 발생할 때, 즉 텍스트에서 일치하는 항목을 찾을 때 필요한 작업을 수행할 수 있습니다. 예를 들어 이 클래스 int start()
와 int end()
메서드를 사용하여 텍스트에서 일치하는 위치를 결정할 수 있습니다. String replaceFirst(String replacement)
그리고 및 String replaceAll(String replacement)
메서드를 사용하여 일치 항목을 대체 매개변수의 값으로 바꿀 수 있습니다 . 예를 들어:
public static void main(String[] args) {
String text = "Fred Anna Alexa";
Pattern pattern = Pattern.compile("A.+?a");
Matcher matcher = pattern.matcher(text);
while (matcher.find()) {
int start=matcher.start();
int end=matcher.end();
System.out.println("Match found: " + text.substring(start, end) + " from index "+ start + " through " + (end-1));
}
System.out.println(matcher.replaceFirst("Ira"));
System.out.println(matcher.replaceAll("Mary"));
System.out.println(text);
}
산출:
Match found: Anna from index 5 through 8
Match found: Alexa from index 10 through 14
Fred Ira Alexa
Fred Mary Mary
Fred Anna Alexa
replaceFirst
이 예제는 및 replaceAll
메소드가 새 String
객체(원본 텍스트의 패턴 일치가 인수로 메소드에 전달된 텍스트로 대체되는 문자열)를 생성 함을 분명히 합니다 . 또한 이 replaceFirst
메서드는 첫 번째 일치 항목만 바꾸지만 replaceAll
텍스트의 모든 일치 항목을 바꿉니다. 원본 텍스트는 변경되지 않습니다. 및 클래스의 가장 빈번한 정규식 연산은 클래스 Pattern
에 Matcher
바로 내장되어 있습니다 String
. split
, matches
, replaceFirst
, 와 같은 방법입니다 replaceAll
. 그러나 후드 아래에서 이러한 메서드는 Pattern
및 Matcher
클래스를 사용합니다. 따라서 추가 코드를 작성하지 않고 프로그램에서 텍스트를 바꾸거나 문자열을 비교하려면 다음 메서드를 사용하십시오.String
수업. 고급 기능이 필요한 경우 Pattern
및 Matcher
클래스를 기억하십시오. 결론
Java 프로그램에서 정규식은 특정 패턴 일치 규칙을 따르는 문자열로 정의됩니다. 코드를 실행할 때 Java 시스템은 이 문자열을 객체로 컴파일하고 객체를Pattern
사용하여 Matcher
텍스트에서 일치하는 항목을 찾습니다. 처음에 말했듯이 사람들은 종종 정규 표현식이 어려운 주제라고 생각하여 나중으로 미루곤 합니다. 그러나 기본 구문, 메타 문자 및 문자 이스케이프를 이해하고 정규 표현식의 예를 연구하면 언뜻 보기보다 훨씬 간단하다는 것을 알게 될 것입니다.
더 읽어보기: |
---|
GO TO FULL VERSION