자바 정규 표현 식 비 포획 그룹 상세 설명

요 며칠 동안 정규 표현 식 을 보고 비 포획 그룹 (non - capturing) 을 정리 했다.
주로 1 개 + 2 조 총 5 개 를 정리 합 니 다.
(?:X) (?=X) (?<=X) (?!X) (?
1. 먼저 (?:) 비 포획 팀 부터 말 합 니 다.
다음은 하나의 예 로 비 포획 그룹 을 끌 어 낸다.
두 가지 금액 이 있 습 니 다. 8899 달러 와 6688 달러 입 니 다. 분명 한 것 은 앞의 것 은 8899 달러 이 고, 뒤의 것 은 6688 달러 입 니 다. 저 는 지금 정규 가 필요 합 니 다. 그들의 화폐 금액 과 화폐 종 류 를 추출 하 라 고 요구 합 니 다. 정규 는 다음 과 같 습 니 다. (\ d) + (65509 달러) $(자바 에서 테스트 하기 때문에 전의 문자 가 많 습 니 다.)
테스트 프로그램 은 다음 과 같 습 니 다.

Pattern p = Pattern.compile("(\\d+)([¥$])$");
String str = "8899¥";
Matcher m = p.matcher(str);
if(m.matches()){
System.out.println(" : " + m.group(1));
System.out.println(" : " + m.group(2));
}

출력 결 과 는:
화폐 금액: 8899
화폐 종류: ¥
OK, 요 구 를 만족 시 켰 습 니 다. 여기 서 정규 화 는 두 그룹 으로 나 뉘 었 습 니 다. 하 나 는 (\ \ d +) 이 고 하 나 는 ([* 65509]) 이 며, 이전 그룹 은 화폐 금액 과 일치 하 며, 다음 그룹 은 화폐 종류 와 일치 합 니 다.
지금, 나 는 이 정규 가 부동 소수점 과 일치 할 수 있 는 것 이 필요 하 다. 예 를 들 어 8899.56 * 65509. 우 리 는 모두 알 고 있다. 지금 은 1 위안 보다 적 으 면 기본적으로 물건 을 살 수 없 기 때문에, 나 는 소수 부분 을 소홀히 하고 싶 으 며, 정규 적 으로 는 8899 와 65509 ℃ 를 추출 하고 싶다.
그렇다면 정 칙 은 다음 과 같다.
(\\d+)(\\.?)(\\d+)([¥$])$

여기 에는 괄호 로 네 그룹 으로 나 뉘 어 져 있 기 때문에 화폐 금액 의 정수 부분 과 화폐 종 류 를 출력 하려 면 각각 group (1), group (4) 에 져 야 합 니 다. 출력 부분 과 정규 가 분리 되 어 있다 면 출력 부분의 코드 를 수정 하지 않 고 정규 만 수정 하고 싶 습 니 다. 즉, group (1), group (2) 을 출력 으로 합 니 다. 이 를 통 해 비 포획 그룹 (?:) 을 끌 어 낼 수 있 습 니 다.
앞의 정규 를 다음 과 같이 수정 합 니 다.
(\\d+)(?:\\.?)(?:\\d+)([¥$])$

이렇게 해서 group (1), group (2) 을 출력 으로 하고 8899 와 65509 를 똑 같이 출력 했다.
이 정규 중간 두 그룹 은 비 포획 그룹 (?:) 을 사용 합 니 다. 포획 하지 않 고 그룹 만 나 누 는 것 으로 이해 할 수 있 습 니 다.
2. (? =) 와 (? < =)
어떤 자 료 는 그것들 을 긍정 적 인 앞으로 찾기 와 긍정 적 인 뒤로 찾기 라 고 한다.
긍정 적 인 순서 로 둘 러 보고 긍정 적 인 역순 으로 둘 러 보 는 자료 도 있다.
1. 그들의 이름 을 무시 하고 다음 의 예 를 보십시오.

Pattern p = Pattern.compile("[0-9a-z]{2}(?=aa)");
String str = "12332aa438aaf";

Matcher m = p.matcher(str);
while(m.find()){
System.out.println(m.group());
}

이 프로그램 출력
이 정규 의 뜻 은 이 문자열 과 일치 합 니 다. 이 문자열 은 두 글자 (숫자 또는 알파벳) 이 고 [color = red] 뒤에 [/ color] 두 개의 a 를 바짝 따 르 고 있 습 니 다.
분석 해 보 세 요:
32aa 라 는 하위 문자열 은 이 조건 을 만족 시 키 기 때문에 일치 할 수 있 습 니 다. 또한 (? =) 부분 은 캡 처 되 지 않 기 때문에 출력 은 32 일 뿐 aa 를 포함 하지 않 습 니 다. 같은 이치 로 38aa 도 이 정규 와 일치 하고 출력 은 38 에 불과 합 니 다.
다시 한 번 깊이 들 어가 보 자.
str 가 처음으로 32 를 성공 적 으로 출력 한 후에 프로그램 은 계속 뒤로 가서 일치 하 는 다른 하위 문자열 이 있 는 지 찾 아야 합 니 다. 그러면 이 때 는 32aa 의 뒷 자리 부터 뒤로 찾 아야 합 니까? 아니면 32 의 뒷 자리 부터 찾 아야 합 니까? 즉, 색인 5 부터 시작 합 니까? 아니면 7 부터 시작 합 니까? 32aa 의 다음 자리 부터 뒤로 찾 아야 합 니 다. 32aa 가 정규 와 일치 하기 때문에 다음 을 찾 아야 합 니 다.한 분 은 당연히 그 뒤에, 즉 4 부터 시작 합 니 다. 그러나 실제로는 32 의 뒤에, 즉 첫 번 째 a 부터 뒤로 찾 습 니 다. 원인 입 니까? (? =) 비 포획 입 니까?
[i] API 문 서 를 찾 아 보 는 것 은 이렇게 설명 되 어 있 습 니 다. [/ i]
[quote](?=X) X, via zero-width positive lookahead[/quote]
제로 - width (0 너비) 를 볼 수 있 는 것 이 바로 이 뜻 입 니 다.
이제 문자열 을 좀 더 생각 나 게 쓰 세 요.
str = "aaaaaaaa";

출력 보기: aa aa aa
분석 해 보 세 요:
이 문자열 은 모두 8 개의 a 가 있다.
첫 번 째 매 칭 은 쉽게 찾 을 수 있 습 니 다. 그것 은 바로 앞의 네 번 째 입 니 다. aaaa 입 니 다. 물론 세 번 째 와 네 번 째 a 는 캡 처 되 지 않 기 때문에 출력 은 첫 번 째 와 두 번 째 a 입 니 다.
이어서 계속 찾 아 보 세 요. 이 때 는 세 번 째 a 부터 시작 해서 셋 에서 여섯 까지 이 네 개의 a 구역 이 배치 되 었 기 때문에 세 번 째 a 와 네 번 째 a 를 출력 합 니 다.
이어서 계속 찾 아 보 세 요. 이 때 는 다섯 번 째 a 부터 시작 해서 다섯 번 째 부터 여덟 번 째 까지 이 네 개의 a 구역 이 배치 되 었 기 때문에 다섯 번 째 a 와 여섯 번 째 a 를 출력 합 니 다.
이 어 뒤 를 돌아 보 니 이 때 는 일곱 번 째 a 부터 시작 되 었 다. 분명히 일곱 번 째 와 여덟 번 째 a 는 정규 적 인 일치 조건 을 만족 시 키 지 못 하고 찾기 가 끝났다.
다시 한 번 연장 해 보 겠 습 니 다. 방금 말 한 상황 은 (? =) 캡 처 한 문자열 뒤에 놓 여 있 습 니 다. 앞 에 놓 으 면 어떤 결과 입 니까?
예:

Pattern p = Pattern.compile("(?=hopeful)hope");
String str = "hopeful";
Matcher m = p.matcher(str);
while(m.find()){
System.out.println(m.group());
}

그것 의 출력 은 hope 이다.
정규 적 인 뜻 은 hopeful 과 일치 할 수 있 는 지, 가능 하 다 면 hopeful 의 hope 를 캡 처 하 는 것 입 니 다. 물론 뒤쪽 으로 일치 하 는 하위 문자열 을 계속 찾 는 것 은 f 부터 입 니 다.
비교 해 보면 (? = hopeful) hope 와 hope (? = ful), 두 정규 의 효 과 는 사실 같다.
2. 다음은 (? < =)
정규 를 고 쳐 라.
Pattern p = Pattern.compile("(?<=aa)[0-9a-z]{2}");

문자열
str = "12332aa438aaf";

출력
이 정규 의 뜻 은 다음 과 같다. 이 문자열 은 두 글자 (숫자 나 자모) 이 고, [color = red] 앞 [/ color] 은 두 글자 a 를 바짝 따 르 는 것 이다.
마찬가지 로 깊이 들 어가 서 str 를
출력 이 무엇 인지 보 세 요.
분석 해 보 세 요:
첫 번 째 매 칭 은 말 할 필요 도 없 이 앞의 네 번 째 a 이 고 세 번 째 와 네 번 째 a 를 출력 합 니 다.
계속 뒤로 찾 아 보 세 요. 다섯 번 째 a 부터 프로그램 에서 다섯 번 째 와 여섯 번 째 a 가 만족 하 는 것 을 발 견 했 습 니 다. 두 글자 이 고 앞 에 두 개의 a (세 번 째 와 네 번 째 a) 가 붙 어 있 는 것 을 만족 시 켰 습 니 다. 그래서 일치 하 는 데 성 공 했 습 니 다. 다섯 번 째 와 여섯 번 째 a 를 출력 합 니 다.
계속 뒤로 찾 아 보 세 요. 일곱 번 째 a 부터 프로그램 은 일곱 번 째 와 여덟 번 째 a 가 만족 하 는 것 을 발 견 했 습 니 다. 두 번 째 문자 이 고 앞 에 두 개의 a (다섯 번 째 와 여섯 번 째 a) 가 붙 어 있 는 것 을 만족 시 켰 습 니 다. 그래서 일치 하 는 데 성 공 했 습 니 다. 일곱 번 째 와 여덟 번 째 a 를 출력 하 였 습 니 다. 검색 이 끝 났 습 니 다.
3. (?!) 와 (? 외관상 으로 보면 앞 조 와 비슷 하 다. 차이 점 은 '=' 을 '!' 로 바 꾸 는 것 이다.
그 의 미 는 정반 대 이다.
[0 - 9a - z] {2} (?! aa) 은 두 글자 가 일치 하고 뒤에 바짝 붙 어 있 는 것 은 aa 가 아니 라 는 뜻 이다.
(? < = aa) [0 - 9a - z] {2} 은 두 글자 가 일치 하고 앞 에 바짝 붙 어 있 는 것 은 aa 가 아니 라 는 뜻 이다.
용법 은 앞에서 말 한 것 과 차이 가 많 지 않 으 니, 여 기 는 더 이상 상술 하지 않 겠 다.

좋은 웹페이지 즐겨찾기