Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
popesArray = [
    "Pope Anastasius I 399-401",
    "Pope Innocent I 401-417",
    "Pope Zosimus 417-418",
    "Pope Boniface I 418-422",
    "Pope Celestine I 422-432",
    "Pope Sixtus III 432-440",
    "Pope Leo I the Great 440-461",
    "Pope Hilarius 461-468",
    "Pope Simplicius 468-483",
    "Pope Felix III 483-492",
    "Pope Gelasius I 492-496",
    "Pope Anastasius II 496-498",
    "Pope Symmachus 498-514"
]

A first attempt at a regular expression to parse out the name (without the sequence number or modifier) and years of each pope might be as follows우선 이름(예를 들어 "Pope Anastasius II" 에서 "Anastasius")과 연도만 정확히 추출하는 정규식을 써보겠습니다:

Code Block
/Pope (.*)(?: .*)? ([0-9]+)-([0-9]+)/

...

/

Pope

(.*)

(?: .*)?

([0-9]+)

-

([0-9]+)

/ begin

expression 문장 시작

Pope

capture some characters

non-capture group: space and some characters

capture a number

-

capture a number

end expression

...

몇 개의 글자들을 잡아내고

비 캡쳐 그룹: 스페이스와 몇 개의 문자들

숫자를 잡아낸 후

-

다시 숫자

그리고 문장의 끝

위 정규식에서 우리는 첫번째 캡쳐 그럼이 교황의 이름을 잡아낼 것을 기대하지만 실제로는 그렇게 되지 않습니다. 너무 많이 잡아내고 있습니다. 예를 들어 첫번째 줄은 다음과 같이 나뉩니다:

/

Pope

(.*)

(?: .*)?

([0-9]+)

-

([0-9]+)

/ begin

expression 문장 시작

Pope

Anastasius I

 

399

-

401

end expression

...

문장 끝

첫번째 캡쳐 그룹이 너무 많은 입력을 잡아내고 있습니다. 우리가 원하는 건 "Anastasius"만 잡는 것입니다. 다시 말하면 첫번째 캡쳐 그룹은 가능한 최소한의 입력만 잡아내어야 합니다. 자바 정규식은 이런 경우에 대비하여 "reluctant" 버전의 *, +, ? 연산자를 제공합니다. 연산자 뒤에 ? 를 붙여서 *?, +?, ??와 같이 표기하면 됩니다. 다음은 이것을 적용한 새 정규식 입니다:

Code Block
/Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/

So now let's look at our new regular expression with the most difficult of the inputs, the one before Pope Hilarius (a real jokester), breaks up as follows이제 가장 복잡해보이는 입력에 대해 정규식을 적용해봅시다:

/

Pope

(.*?)

(?: .*)?

([0-9]+)

-

([0-9]+)

/ begin

expression 문장 시작

Pope

Leo

I the Great

440

-

461

end expression

Which is what we want.

...

문장 끝

정확히 우리가 원하는 결과입니다.

다음 코드를 통해 위에서 설명한 내용들을 테스트할 수 있습니다:

Code Block
popesArray = [
    "Pope Anastasius I 399-401",
    "Pope Innocent I 401-417",
    "Pope Zosimus 417-418",
    "Pope Boniface I 418-422",
    "Pope Celestine I 422-432",
    "Pope Sixtus III 432-440",
    "Pope Leo I the Great 440-461",
    "Pope Hilarius 461-468",
    "Pope Simplicius 468-483",
    "Pope Felix III 483-492",
    "Pope Gelasius I 492-496",
    "Pope Anastasius II 496-498",
    "Pope Symmachus 498-514"
]

myClosure = {
	myMatcher = (it =~ /Pope (.*?)(?: .*)? ([0-9]+)-([0-9]+)/);
	if (myMatcher.matches())
		println(myMatcher[0][1]+": "+myMatcher[0][2]+" to "+myMatcher[0][3]);
}
popesArray.each(myClosure);

Try this code with the original regular expression as well to see the broken output.수정하기 전의 정규식을 사용해서 위 예제를 다시 시도해보세요. 출력이 어떻게 깨지는지 살펴볼 수 있습니다.