JavaRush /Java Blog /Random-KO /Java의 정규 표현식, 3부

Java의 정규 표현식, 3부

Random-KO 그룹에 게시되었습니다
우리는 Javaworld 웹사이트 를 위해 Jeff Friesen이 작성한 Java 정규식에 대한 짧은 가이드의 번역을 여러분의 주의에 제시합니다 . 읽기 쉽도록 기사를 여러 부분으로 나누었습니다. Java의 정규 표현식, 3부 - 1Java 정규식, 1부 Java 정규식, 2부

Regex API를 사용하여 일반적인 프로그래밍 작업 단순화

이 기사의 1부와 2부에서는 정규식과 Regex API를 소개했습니다. 클래스에 대해 배웠고 Pattern리터럴 문자열을 사용하는 간단한 패턴 일치부터 범위, 경계 일치자 및 수량자를 사용하는 보다 복잡한 일치까지 정규식 구성을 보여주는 예제를 살펴보았습니다. 이 부분과 후속 부분에서는 첫 번째 부분에서 다루지 않은 문제를 고려하고 클래스의 해당 메서드를 연구할 것 입니다 Pattern. 또한 일반적인 프로그래밍 문제를 더 쉽게 만들기 위해 정규식을 사용하는 두 가지 유틸리티를 배우게 됩니다 . 첫 번째는 문서화를 위해 코드에서 주석을 추출합니다. 두 번째는 어셈블러, 컴파일러 및 유사한 소프트웨어의 필수 구성 요소인 어휘 분석을 수행하도록 설계된 재사용 가능한 코드 라이브러리입니다. MatcherPatternSyntaxException

소스 코드 다운로드

여기에서 이 기사의 데모 애플리케이션에 대한 모든 소스 코드(Jeff Friesen이 JavaWorld를 위해 생성)를 얻을 수 있습니다 .

정규식 API 학습

Pattern, Regex API를 구성하는 세 가지 클래스입니다 Matcher. PatternSyntaxException각각은 코드에서 정규식을 사용할 수 있는 메서드를 제공합니다.

Pattern 클래스의 메서드

클래스의 인스턴스는 Pattern패턴이라고도 알려진 컴파일된 정규식입니다. 정규식은 패턴 일치 작업의 성능을 향상시키기 위해 컴파일됩니다. 다음 정적 메서드는 컴파일을 지원합니다.
  • Pattern compile(String regex)콘텐츠를 regex새로운 Pattern. 이 메서드는 성공하면 개체에 대한 참조를 반환하고, PatternSyntaxException잘못된 정규식 구문이 감지되면 예외를 발생시킵니다. Matcher이 객체 에서 사용되거나 이 객체에서 반환된 클래스의 모든 객체는 Pattern대소문자 구분 검색과 같은 기본 설정을 사용합니다. 예를 들어, 코드 조각은 점 문자로 시작하는 문자열과 일치하는 정규식의 컴파일된 표현을 저장하는 Pattern p = Pattern.compile("(?m)^\\."); 개체를 만듭니다 .Pattern

  • Pattern compile(String regex, int flags)와 동일한 문제를 해결 하지만 OR 유형의 비트 플래그에 대한 비트 상수 세트를 Pattern compile(String regex)고려합니다 . flags클래스는 비트별 OR(예: )를 사용하여 결합하고 인수로 전달할 수 있는 Pattern상수를 선언합니다 .CANON_EQ, CASE_INSENSITIVE, COMMENTS, DOTALL, LITERAL, MULTILINE, UNICODE_CASE, UNICODE_CHARACTER_CLASS и UNIX_LINESCASE_INSENSITIVE | DOTALLflags

  • 를 제외하고 CANON_EQ, LITERAL и UNICODE_CHARACTER_CLASS이러한 상수는 1부에서 설명한 중첩 플래그 표현식의 대안입니다. 클래스에 정의된 것과 다른 플래그 상수가 발견되면 Pattern메소드에서 Pattern compile(String regex, int flags) 예외가 발생합니다 java.lang.IllegalArgumentException. 예를 들어 Pattern p = Pattern.compile("^\\.", Pattern.MULTILINE);이전 예제와 동일하며 상수 Pattern.MULTILINE와 중첩된 플래그 표현식이 (?m)동일한 작업을 수행합니다.
때로는 object 로 컴파일된 정규식의 원래 문자열 복사본 Pattern과 사용되는 플래그를 가져와야 하는 경우도 있습니다. 이렇게 하려면 다음 메서드를 호출하면 됩니다.
  • String pattern()로 컴파일된 원래 정규식 문자열을 반환합니다 Pattern.

  • int flags()객체의 플래그를 반환합니다 Pattern.
객체를 받은 후 일반적으로 패턴 일치 작업을 수행하기 위해 Pattern객체를 얻는 데 사용됩니다 . Matcher이 메서드는 텍스트에서 개체 패턴과 일치하는 항목을 검색하는 Matcher matcher(Charsequence input)개체를 만듭니다 . 호출되면 이 객체에 대한 참조를 반환합니다 . 예를 들어, 명령은 변수가 참조하는 개체에 대해 반환합니다 . MatcherinputPatternMatcherMatcher m = p.matcher(args[1]);MatcherPatternp
일회성 검색
static boolean matches(String regex, CharSequence input)클래스 메소드를 사용 하면 객체 생성 및 템플릿을 사용한 일회성 검색 Pattern비용을 줄일 수 있습니다 . 이 메서드는 패턴이 일치 하면 true를 반환하고 , 그렇지 않으면 false를 반환합니다. 정규식에 구문 오류가 포함된 경우 메서드에서 예외가 발생합니다 . 예를 들어 를 인쇄하여 문구에 공백과 소문자만 포함되어 있는지 확인합니다. PatternMatcherinputregexPatternSyntaxExceptionSystem.out.println(Pattern.matches("[a-z[\\s]]*", "all lowercase letters and whitespace only"));trueall lowercase letters and whitespace only
Java의 정규 표현식, 3부 - 2

텍스트 분할

대부분의 개발자는 텍스트 기반 직원 계정을 필드 집합으로 변환하는 것과 같이 입력 텍스트를 구성 요소 부분으로 나누는 코드를 한 번 이상 작성했습니다. 이 클래스는 Pattern두 가지 텍스트 분할 방법을 사용하여 이 지루한 작업을 보다 편리하게 해결할 수 있는 기능을 제공합니다.
  • 이 메서드는 찾은 개체 패턴과 일치하는 항목에 따라 String[] split(CharSequence text, int limit)분할 하고 결과를 배열로 반환합니다. 각 배열 요소는 패턴 일치 텍스트 조각(또는 텍스트 끝)으로 다음 시퀀스와 구분된 텍스트 시퀀스를 지정합니다. 배열의 요소는 에 나타나는 순서와 동일합니다 .textPatterntext

    이 방법에서 배열 요소의 수는 limit찾을 일치 항목의 수를 제어하는 ​​매개변수에 따라 달라집니다.

    • 양수 값은 일치 하는 항목만 검색하며 limit-1배열의 길이는 요소 이하입니다 limit.
    • 값이 음수이면 가능한 모든 일치 항목이 검색되며 배열 길이는 임의적일 수 있습니다.
    • 값이 0이면 가능한 모든 일치 항목이 검색되고 배열 길이는 임의적일 수 있으며 끝에 있는 빈 줄은 삭제됩니다.

  • 이 메서드는 String[] split(CharSequence text)0을 제한 인수로 사용하여 이전 메서드를 호출하고 호출 결과를 반환합니다.
split(CharSequence text)다음은 직원 계정을 이름, 나이, 우편 주소 및 급여라는 별도의 필드로 분할하는 문제를 해결하는 방법의 결과입니다 .
Pattern p = Pattern.compile(",\\s");
String[] fields = p.split("John Doe, 47, Hillsboro Road, 32000");
for (int i = 0; i < fields.length; i++)
   System.out.println(fields[i]);
위의 코드는 쉼표 문자 바로 뒤에 단일 공백 ​​문자가 오는 것을 찾는 정규식을 설명합니다. 실행 결과는 다음과 같습니다.
John Doe
47
Hillsboro Road
32000

템플릿 조건자 및 Streams API

Java 8에서는 클래스에 Pattern메소드가 나타났습니다 . 이 메서드는 패턴을 일치시키는 데 사용되는 조건자(부울 값이 있는 함수)를 생성합니다. 이 메서드의 사용은 다음 코드 조각에 나와 있습니다. Predicate asPredicate()
List progLangs = Arrays.asList("apl", "basic", "c", "c++", "c#", "cobol", "java", "javascript", "perl", "python", "scala");
Pattern p = Pattern.compile("^c");
progLangs.stream().filter(p.asPredicate()).forEach(System.out::println);
이 코드는 프로그래밍 언어 이름 목록을 만든 다음 패턴을 컴파일하여 문자로 시작하는 모든 이름을 찾습니다 c. 위 코드의 마지막 줄은 이 목록을 소스로 사용하여 직렬 데이터 스트림 수신을 구현합니다. asPredicate()이름이 문자로 시작 c하고 스트림을 반복하여 일치하는 이름을 표준 출력에 인쇄할 때 true를 반환하는 부울 함수를 사용하여 필터를 설정합니다 . 이 마지막 줄은 Part 1의 RegexDemo 애플리케이션에서 친숙한 다음 일반 루프와 동일합니다.
for (String progLang: progLangs)
   if (p.matcher(progLang).find())
      System.out.println(progLang);

Matcher 클래스 메서드

클래스의 인스턴스는 Matcher클래스의 컴파일된 정규 표현식을 해석하여 일련의 문자에 대해 패턴 일치 작업을 수행하는 메커니즘을 설명합니다 Pattern. 클래스의 객체는 Matcher다양한 유형의 패턴 검색 작업을 지원합니다.
  • 이 메서드는 boolean find()입력 텍스트에서 다음 일치 항목을 검색합니다. 이 메서드는 지정된 텍스트의 시작 부분이나 이전 일치 항목 뒤의 첫 번째 문자부터 검색을 시작합니다. 두 번째 옵션은 이 메서드에 대한 이전 호출이 true를 반환하고 확인자가 재설정되지 않은 경우에만 가능합니다. 어떤 경우든 검색에 성공하면 부울 값 true가 반환됩니다. 이 방법의 예는 RegexDemo1부에서 찾을 수 있습니다.

  • 이 메서드는 boolean find(int start)일치자를 재설정하고 텍스트에서 다음 일치 항목을 검색합니다. 매개변수에 지정된 위치부터 보기가 시작됩니다 start. 검색이 성공하면 부울 값 true가 반환됩니다. 예를 들어 m.find(1);위치(위치 0은 무시됨)부터 시작하여 텍스트를 검색합니다 1. 매개변수에 start음수 값이나 일치자 텍스트 길이보다 큰 값이 포함되어 있으면 메서드에서 예외가 발생합니다 java.lang.IndexOutOfBoundsException.

  • 이 메서드는 boolean matches()모든 텍스트를 패턴과 일치시키려고 시도합니다. 모든 텍스트가 패턴과 일치하면 부울 값 true를 반환합니다. 예를 들어 해당 문자가 단어 문자가 아니기 때문에 코드가 Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.matches());출력됩니다 .false!

  • 이 메서드는 boolean lookingAt()지정된 텍스트를 패턴과 일치시키려고 시도합니다. 이 메서드는 텍스트의 일부가 패턴과 일치하면 true를 반환합니다. 메서드와 달리 matches();모든 텍스트가 패턴과 일치할 필요는 없습니다. 예를 들어, 텍스트의 시작 부분이 단어 형성 문자로만 구성되어 있으므로 Pattern p = Pattern.compile("\\w*"); Matcher m = p.matcher("abc!"); System.out.println(p.lookingAt());출력됩니다 .trueabc!

클래스 객체와 달리 Pattern클래스 객체는 Matcher상태 정보를 유지합니다. 때로는 패턴 검색이 완료된 후 이 정보를 지우기 위해 일치자를 재설정해야 할 수도 있습니다. 리졸버를 재설정하는 데 다음 방법을 사용할 수 있습니다.
  • 이 메서드는 Matcher reset()끝에 추가할 위치를 포함하여 일치자의 상태를 재설정합니다(0으로 재설정). 다음 패턴 검색 작업은 일치자 텍스트의 시작 부분에서 시작됩니다. 현재 객체에 대한 참조를 반환합니다 Matcher. 예를 들어 에서 m.reset();참조하는 해석기를 재설정합니다 m.

  • 이 메서드는 Matcher reset(CharSequence text)해석기 상태를 재설정하고 새 해석기 텍스트를 로 설정합니다 text. 다음 패턴 검색 작업은 새 일치자 텍스트의 시작 부분에서 시작됩니다. 현재 객체에 대한 참조를 반환합니다 Matcher. 예를 들어 m.reset("new text");참조된 해석기를 재설정 m하고 새 해석기 텍스트를 로 설정합니다 "new text".

Java의 정규 표현식, 3부 - 3

끝에 텍스트 추가

끝에 추가될 일치자의 위치는 유형의 객체 끝에 추가되는 일치자 텍스트의 시작을 지정합니다 java.lang.StringBuffer. 다음 방법에서는 이 위치를 사용합니다.
  • 이 메서드는 일치자 텍스트 문자를 읽고 이를 인수가 참조하는 Matcher appendReplacement(StringBuffer sb, String replacement)개체의 끝에 추가합니다 . 이 메서드는 이전 패턴 일치 앞의 마지막 문자에서 읽기를 중지합니다. 그런 다음 메서드는 인수가 참조하는 유형 개체의 문자를 개체 끝에 추가합니다 (문자열에는 이전 검색 중에 캡처된 텍스트 시퀀스에 대한 참조가 포함될 수 있습니다. 이러한 참조는 캡처되는 문자 및 그룹 번호를 사용하여 지정됩니다). 마지막으로, 이 메서드는 마지막으로 일치하는 문자 위치에 1을 더한 일치자 위치 값을 설정한 다음 현재 일치자에 대한 참조를 반환합니다.StringBuffersbStringreplacementStringBufferreplacement($)

  • 매처가 아직 일치 항목을 찾지 못했거나 이전 검색 시도가 실패한 경우 메서드는 Matcher appendReplacement(StringBuffer sb, String replacement)예외를 발생시킵니다 . 행이 패턴에 없는 캡처 그룹을 지정하는 경우 java.lang.IllegalStateException예외가 발생합니다 .IndexOutOfBoundsExceptionreplacement

  • 이 메서드는 StringBuffer appendTail(StringBuffer sb)모든 텍스트를 개체에 추가 StringBuffer하고 해당 개체에 대한 참조를 반환합니다. 마지막 메소드 호출 후 appendReplacement(StringBuffer sb, String replacement)메소드를 호출하여 appendTail(StringBuffer sb)나머지 텍스트를 객체에 복사합니다 StringBuffer.

캡처된 그룹
1부에서 기억했듯이 캡처 그룹은 괄호( ()) 메타 문자로 묶인 일련의 문자입니다. 이 구성의 목적은 나중에 패턴 일치 중에 재사용할 수 있도록 발견된 문자를 저장하는 것입니다. 패턴 검색 중에는 캡처된 그룹의 모든 문자가 하나의 전체로 간주됩니다.
다음 코드는 appendReplacement(StringBuffer sb, String replacement)및 메서드를 호출하여 appendTail(StringBuffer sb소스 텍스트의 모든 문자 시퀀스를 cat다음으로 바꿉니다 caterpillar.
Pattern p = Pattern.compile("(cat)");
Matcher m = p.matcher("one cat, two cats, or three cats on a fence");
StringBuffer sb = new StringBuffer();
while (m.find())
   m.appendReplacement(sb, "$1erpillar");
m.appendTail(sb);
System.out.println(sb);
캡처된 그룹과 이에 대한 참조를 대체 텍스트에 사용하면 프로그램이 가 erpillar나타날 때마다 삽입하도록 지시합니다 cat. 이 코드를 실행한 결과는 다음과 같습니다. one caterpillar, two caterpillars, or three caterpillars on a fence

텍스트 바꾸기

이 클래스 MatcherappendReplacement(StringBuffer sb, String replacement). 이러한 방법을 사용하면 [대체된 텍스트]의 첫 번째 항목 또는 모든 항목을 바꿀 수 있습니다.
  • 이 메소드는 String replaceFirst(String replacement)일치자를 재설정하고, 새 객체를 생성하고 String, 일치자 텍스트의 모든 문자(첫 번째 일치 항목까지)를 이 문자열에 복사하고, 해당 문자열의 끝에 문자를 추가하고 replacement, 나머지 문자를 문자열에 복사하고 반환합니다. 개체 String(문자열에는 replacement달러 기호 및 캡처된 그룹 번호를 사용하여 이전 검색 텍스트 시퀀스 중에 캡처된 항목에 대한 참조가 포함될 수 있음)

  • 이 메서드는 String replaceAll(String replacement)메서드와 유사하게 작동 String replaceFirst(String replacement)하지만 replacement발견된 모든 일치 항목을 문자열의 문자로 바꿉니다.

정규식은 \s+입력 텍스트에서 하나 이상의 공백 문자를 검색합니다. 아래에서는 이 정규식을 사용하고 replaceAll(String replacement)중복 공백을 제거하는 메서드를 호출합니다.
Pattern p = Pattern.compile("\\s+");
Matcher m = p.matcher("Удаляем      \t\t лишние пробелы.   ");
System.out.println(m.replaceAll(" "));
결과는 다음과 같습니다. Удаляем лишние пробелы. Java의 정규식, 4부 Java의 정규식, 5부
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION