자바 정규식, Part 1 : 패턴 매칭 및 패턴 클래스

Java의 문자 및 분류 된 문자열 클래스는 패턴 일치에 대한 저수준 지원을 제공하지만 일반적으로 이러한 지원은 복잡한 코드로 이어집니다. 더 간단하고 효율적인 코딩을 위해 Java는 Regex API를 제공합니다. 이 두 부분으로 구성된 자습서는 정규식 및 Regex API를 시작하는 데 도움이됩니다. 먼저 java.util.regex패키지 에있는 세 가지 강력한 클래스의 압축을 푼 다음 Pattern클래스와 정교한 패턴 일치 구조를 살펴 보겠습니다 .

다운로드 코드 받기이 자습서에서 예제 응용 프로그램의 소스 코드를 다운로드합니다. JavaWorld를 위해 Jeff Friesen이 만들었습니다.

정규식이란 무엇입니까?

정규식 이라고도, 정규식 또는 정규 표현식 , 그 문자열 인 패턴 (템플릿) 스트링의 집합을 설명한다. 패턴은 세트에 속하는 문자열을 결정합니다. 패턴은 리터럴 문자와 메타 문자 로 구성되며 리터럴 의미 대신 특별한 의미를 갖는 문자입니다.

패턴 일치일치 또는 정규식의 패턴과 일치하는 문자열 을 식별하기 위해 텍스트를 검색하는 프로세스입니다 . Java는 Regex API를 통해 패턴 일치를 지원합니다. API는 세 가지 classes-- 구성 Pattern, MatcherPatternSyntaxException--all에 위치한 java.util.regex패키지 :

  • Pattern패턴 이라고도하는 객체 는 컴파일 된 정규식입니다.
  • Matcherobject 또는 matcher 는 패턴을 해석하여 문자 시퀀스 (클래스가 java.lang.CharSequence인터페이스를 구현하고 텍스트 소스 역할을 하는 객체) 에서 일치 항목을 찾는 엔진입니다 .
  • PatternSyntaxException 개체는 잘못된 정규식 패턴을 설명합니다.

Java는 java.lang.String클래스의 다양한 메소드를 통해 패턴 일치를 지원합니다 . 예를 들어, 호출 문자열이 의 정규식 과 정확히 일치하는 경우에만boolean matches(String regex) true를 반환합니다 .regex

편리한 방법

내부적 matches()String의 다른 정규식 중심의 편리한 메소드는 정규식 API의 관점에서 구현됩니다.

RegexDemo

내가 만든 RegexDemo자바의 정규 표현식과에있는 다양한 방법을 보여주기 위해 응용 프로그램 Pattern, MatcherPatternSyntaxException클래스를. 데모의 소스 코드는 다음과 같습니다.

목록 1. 정규식 시연

import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class RegexDemo { public static void main(String[] args) { if (args.length != 2) { System.err.println("usage: java RegexDemo regex input"); return; } // Convert new-line (\n) character sequences to new-line characters. args[1] = args[1].replaceAll("\\\\n", "\n"); try { System.out.println("regex = " + args[0]); System.out.println("input = " + args[1]); Pattern p = Pattern.compile(args[0]); Matcher m = p.matcher(args[1]); while (m.find()) System.out.println("Found [" + m.group() + "] starting at " + m.start() + " and ending at " + (m.end() - 1)); } catch (PatternSyntaxException pse) { System.err.println("Bad regex: " + pse.getMessage()); System.err.println("Description: " + pse.getDescription()); System.err.println("Index: " + pse.getIndex()); System.err.println("Incorrect pattern: " + pse.getPattern()); } } }

우선 RegexDemomain()방법은 수행은 명령 행을 확인하는 것입니다. 여기에는 두 개의 인수가 필요합니다. 첫 번째 인수는 정규식이고 두 번째 인수는 정규식과 일치시킬 입력 텍스트입니다.

\n입력 텍스트의 일부로 줄 바꾸기 ( ) 문자 를 지정할 수 있습니다 . 이를 수행하는 유일한 방법은 \문자 다음에 문자 를 지정하는 것 n입니다. main()이 문자 시퀀스를 유니 코드 값 10으로 변환합니다.

RegexDemo의 코드 대부분은 try- catch구문에 있습니다. try블록 최초로 지정된 정규식과 입력 텍스트를 출력 한 후, 생성 Pattern대상이 저장 컴파일 된 정규식. (정규식은 패턴 일치 중에 성능을 향상시키기 위해 컴파일됩니다.) 일치자는 Pattern개체 에서 추출되고 일치 항목이 남아 있지 않을 때까지 반복적으로 검색하는 데 사용됩니다. catch다양한 원용하는 블록 PatternSyntaxException방법은 예외에 대한 유용한 정보를 추출합니다. 이 정보는 이후에 출력됩니다.

이 시점에서 소스 코드의 작동에 대해 더 많이 알 필요는 없습니다. Part 2에서 API를 살펴보면 분명해질 것입니다.하지만 Listing 1을 컴파일해야합니다. 목록 1의 코드를 가져 와서 컴파일 할 명령 줄에 다음을 입력합니다 RegexDemo.

javac RegexDemo.java

패턴과 그 구조

PatternRegex API를 구성하는 세 클래스 중 첫 번째 클래스는 정규식의 컴파일 된 표현입니다. Pattern의 SDK 문서는 다양한 정규식 구성을 설명하지만 이미 열렬한 정규식 사용자가 아니라면 문서의 일부로 혼동 될 수 있습니다. 수량 자는 무엇이며 탐욕 , 꺼림 , 소유 수량 의 차이점은 무엇 입니까? 무엇 문자 클래스 , 경계 정합 기 , 다시 참조 하고, 내장 플래그 표현식은 ? 다음 섹션에서 이러한 질문에 대한 답변을 드리겠습니다.

리터럴 문자열

가장 간단한 정규식 구조는 리터럴 문자열입니다. 성공적인 패턴 일치를 위해서는 입력 텍스트의 일부가이 구조의 패턴과 일치해야합니다. 다음 예를 고려하십시오.

java RegexDemo apple applet

이 예제 appleapplet입력 텍스트에 패턴 과 일치하는 것이 있는지 발견하려고 시도 합니다. 다음 출력은 일치를 보여줍니다.

regex = apple input = applet Found [apple] starting at 0 and ending at 4

출력은 정규식과 입력 텍스트를 보여준 다음 apple내에서 성공적으로 일치 함을 나타냅니다 applet. : 또한, 그 경기의 시작과 끝 인덱스를 제시 0하고 4각각. 시작 색인은 패턴 일치가 발생하는 첫 번째 텍스트 위치를 식별합니다. 끝 색인은 일치의 마지막 텍스트 위치를 식별합니다.

이제 다음 명령 줄을 지정한다고 가정합니다.

java RegexDemo apple crabapple

이번에는 시작 및 종료 인덱스가 다른 다음 일치 항목을 얻습니다.

regex = apple input = crabapple Found [apple] starting at 4 and ending at 8

applet정규식이고 apple입력 텍스트 인 반대 시나리오 는 일치하지 않음을 나타냅니다. 전체 정규식이 일치해야하며이 경우 입력 텍스트에 tafter가 포함되지 않습니다 apple.

메타 문자

보다 강력한 정규식 구문은 리터럴 문자와 메타 문자를 결합합니다. 예를 들어에서 a.b마침표 메타 문자 ( .)는 a과 사이에 나타나는 모든 문자를 나타냅니다 b. 다음 예를 고려하십시오.

java RegexDemo .ox "The quick brown fox jumps over the lazy ox."

이 예제 .ox는 정규식 및 The quick brown fox jumps over the lazy ox.입력 텍스트로 지정 합니다. RegexDemo문자로 시작하고로 끝나는 일치 항목을 텍스트에서 검색합니다 ox. 다음 출력을 생성합니다.

regex = .ox input = The quick brown fox jumps over the lazy ox. Found [fox] starting at 16 and ending at 18 Found [ ox] starting at 39 and ending at 41

The output reveals two matches: fox and ox (with the leading space character). The . metacharacter matches the f in the first match and the space character in the second match.

What happens when we replace .ox with the period metacharacter? That is, what output results from specifying the following command line:

java RegexDemo . "The quick brown fox jumps over the lazy ox."

Because the period metacharacter matches any character, RegexDemo outputs a match for each character (including the terminating period character) in the input text:

regex = . input = The quick brown fox jumps over the lazy ox. Found [T] starting at 0 and ending at 0 Found [h] starting at 1 and ending at 1 Found [e] starting at 2 and ending at 2 Found [ ] starting at 3 and ending at 3 Found [q] starting at 4 and ending at 4 Found [u] starting at 5 and ending at 5 Found [i] starting at 6 and ending at 6 Found [c] starting at 7 and ending at 7 Found [k] starting at 8 and ending at 8 Found [ ] starting at 9 and ending at 9 Found [b] starting at 10 and ending at 10 Found [r] starting at 11 and ending at 11 Found [o] starting at 12 and ending at 12 Found [w] starting at 13 and ending at 13 Found [n] starting at 14 and ending at 14 Found [ ] starting at 15 and ending at 15 Found [f] starting at 16 and ending at 16 Found [o] starting at 17 and ending at 17 Found [x] starting at 18 and ending at 18 Found [ ] starting at 19 and ending at 19 Found [j] starting at 20 and ending at 20 Found [u] starting at 21 and ending at 21 Found [m] starting at 22 and ending at 22 Found [p] starting at 23 and ending at 23 Found [s] starting at 24 and ending at 24 Found [ ] starting at 25 and ending at 25 Found [o] starting at 26 and ending at 26 Found [v] starting at 27 and ending at 27 Found [e] starting at 28 and ending at 28 Found [r] starting at 29 and ending at 29 Found [ ] starting at 30 and ending at 30 Found [t] starting at 31 and ending at 31 Found [h] starting at 32 and ending at 32 Found [e] starting at 33 and ending at 33 Found [ ] starting at 34 and ending at 34 Found [l] starting at 35 and ending at 35 Found [a] starting at 36 and ending at 36 Found [z] starting at 37 and ending at 37 Found [y] starting at 38 and ending at 38 Found [ ] starting at 39 and ending at 39 Found [o] starting at 40 and ending at 40 Found [x] starting at 41 and ending at 41 Found [.] starting at 42 and ending at 42

Quoting metacharacters

To specify . or any metacharacter as a literal character in a regex construct, quote the metacharacter in one of the following ways:

  • Precede the metacharacter with a backslash character.
  • Place the metacharacter between \Q and \E (e.g., \Q.\E).

Remember to double each backslash character (as in \\. or \\Q.\\E) that appears in a string literal such as String regex = "\\.";. Don't double the backslash character when it appears as part of a command-line argument.

Character classes

We sometimes need to limit characters that will produce matches to a specific character set. For example, we might search text for vowels a, e, i, o, and u, where any occurrence of a vowel indicates a match. A character class identifies a set of characters between square-bracket metacharacters ([ ]), helping us accomplish this task. Pattern supports simple, negation, range, union, intersection, and subtraction character classes. We'll look at all of these below.

Simple character class

The simple character class consists of characters placed side by side and matches only those characters. For example, [abc] matches characters a, b, and c.

Consider the following example:

java RegexDemo [csw] cave

This example matches only c with its counterpart in cave, as shown in the following output:

regex = [csw] input = cave Found [c] starting at 0 and ending at 0

Negation character class

The negation character class begins with the ^ metacharacter and matches only those characters not located in that class. For example, [^abc] matches all characters except a, b, and c.

Consider this example:

java RegexDemo "[^csw]" cave

Note that the double quotes are necessary on my Windows platform, whose shell treats the ^ character as an escape character.

This example matches a, v, and e with their counterparts in cave, as shown here:

regex = [^csw] input = cave Found [a] starting at 1 and ending at 1 Found [v] starting at 2 and ending at 2 Found [e] starting at 3 and ending at 3

Range character class

The range character class consists of two characters separated by a hyphen metacharacter (-). All characters beginning with the character on the left of the hyphen and ending with the character on the right of the hyphen belong to the range. For example, [a-z] matches all lowercase alphabetic characters. It's equivalent to specifying [abcdefghijklmnopqrstuvwxyz].

Consider the following example:

java RegexDemo [a-c] clown

This example matches only c with its counterpart in clown, as shown:

regex = [a-c] input = clown Found [c] starting at 0 and ending at 0

Merging multiple ranges

You can merge multiple ranges into the same range character class by placing them side by side. For example, [a-zA-Z] matches all lowercase and uppercase alphabetic characters.

Union character class

The union character class consists of multiple nested character classes and matches all characters that belong to the resulting union. For example, [a-d[m-p]] matches characters a through d and m through p.

Consider the following example:

java RegexDemo [ab[c-e]] abcdef

This example matches a, b, c, d, and e with their counterparts in abcdef:

regex = [ab[c-e]] input = abcdef Found [a] starting at 0 and ending at 0 Found [b] starting at 1 and ending at 1 Found [c] starting at 2 and ending at 2 Found [d] starting at 3 and ending at 3 Found [e] starting at 4 and ending at 4

Intersection character class

The intersection character class consists of characters common to all nested classes and matches only common characters. For example, [a-z&&[d-f]] matches characters d, e, and f.

Consider the following example:

java RegexDemo "[aeiouy&&[y]]" party

셸이 &문자를 명령 구분 기호로 취급하는 Windows 플랫폼에서는 큰 따옴표가 필요합니다 .

이 예는 다음의 해당 항목 y과 만 일치합니다 party.

regex = [aeiouy&&[y]] input = party Found [y] starting at 4 and ending at 4