내 연락처 정보
우편메소피아@프로톤메일.com
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
정규식에서는? 이는 {0, 1}에 해당하는 0 또는 1번 수량을 나타내거나 다른 의미를 나타내는 특수 문자로 사용될 수 있습니다.
? 뒤에 다른 수량 한정자가 오면 탐욕스럽지 않은 일치, 즉 검색된 가능한 가장 짧은 문자열과 일치함을 나타냅니다.
예를 살펴보겠습니다:
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("a.*?");
- Matcher matcher = pattern.matcher("abcabc");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- }
- }
실행 후 출력: abcabc
최단시간 일치 아닌가요? 왜 실패했나요?
이는 실제로 탐욕스럽지 않은 일치 규칙을 포함합니다.비탐욕적 매칭(Non-greedy match)은 다음 규칙 이전에 최단 경로를 매칭하는 방식으로, 다음 규칙이 없을 경우 탐욕적 매칭으로 처리된다.
즉, "a.*?"만 나타나는 경우에도 그리디 매칭에 따라 처리됩니다.
올바른 사용법을 살펴보겠습니다.
- @Test
- public void test() {
- Pattern pattern = Pattern.compile("(a.*?)(.*)");
- Matcher matcher = pattern.matcher("afcafc");
- if (matcher.matches()) {
- System.out.println(matcher.group(0));
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2));
- }
- }
실행 후 출력:
- afcafc
- a
- fcafc
보시다시피 첫 번째 캡처링 그룹은 가장 짧은 문자열 "a"를 캡처하고 두 번째 캡처링 그룹은 "fcafc"를 캡처합니다.
다른 두 가지 상황을 살펴보겠습니다.
캡처링 그룹에서 사용되는 경우 정규식 앞에 ?:가 배치되어 일치하지만 캡처되지 않음을 나타냅니다. 즉, 이 일치하는 값 그룹은 그룹 방법을 통해 얻을 수 없습니다.
예를 보자
- @Test
- public void test0() {
- Pattern pattern = Pattern.compile("\d{4}-(?:[a-z]+)");
- Matcher matcher = pattern.matcher("3214-opo");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1)); // 报错
- }
- }
그룹(1)을 통해 캡처할 때 오류가 보고됩니다. 즉, 일치할 수는 있지만 캡처할 수는 없습니다. ?:를 제거하면 group(1)을 사용하여 정상적으로 캡처할 수 있습니다.
(?s)는 오른쪽의 한 줄 모드를 활성화하여 .가 개행 문자 n을 포함한 모든 문자와 일치하도록 합니다.
예를 살펴보겠습니다:
- private static final String DEFAULT_VARIABLE_PATTERN = "((?s).*)";
-
-
- /**
- * 从输出结果可知,匹配到了换行符 'n'
- */
- @Test
- public void test4() {
- Pattern pattern = Pattern.compile(DEFAULT_VARIABLE_PATTERN);
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- System.out.println(matcher.group(2)); // (?s) 不能作为捕获组,报错
- }
- }
캡처 시 (?s)는 캡처 그룹으로 캡처할 수 없으므로 "((?s).*)"는 최대 그룹(1)을 캡처할 수 있으며, 그룹(2) 캡처 시 오류가 보고됩니다.
- @Test
- public void test5() {
- Pattern pattern = Pattern.compile("(.*)");
- Matcher matcher = pattern.matcher("abcnsdf");
- if (matcher.matches()) {
- System.out.println(matcher.group());
- System.out.println(matcher.group(1));
- }
- }
(?s)를 제거한 후 "abcnsdf"를 일치시켜 보십시오. 개행 문자가 있기 때문에 일치가 완료되지 않으므로 아무것도 출력되지 않습니다.