sourcecode

정규식을 사용하여 여러 줄 텍스트 일치

copyscript 2022. 8. 3. 23:07
반응형

정규식을 사용하여 여러 줄 텍스트 일치

java를 사용하여 여러 줄의 텍스트를 매칭하려고 합니다.를 사용할 때Pattern와의 클래스Pattern.MULTILINE수식어, 매칭은 할 수 있지만,(?m).

와 같은 패턴입니다.(?m)및 사용String.matches동작하지 않는 것 같습니다.

제가 뭔가 놓친 게 있는 게 분명한데, 뭐가 뭔지 모르겠어요.정규 표현을 잘하지 못합니다.

이게 내가 시도했던 거야

String test = "User Comments: This is \t a\ta \n test \n\n message \n";

String pattern1 = "User Comments: (\\W)*(\\S)*";
Pattern p = Pattern.compile(pattern1, Pattern.MULTILINE);
System.out.println(p.matcher(test).find());  //true

String pattern2 = "(?m)User Comments: (\\W)*(\\S)*";
System.out.println(test.matches(pattern2));  //false - why?

첫째, 잘못된 가정 하에 수식어를 사용하고 있습니다.

Pattern.MULTILINE또는(?m)Java에게 앵커를 받아들이도록 지시합니다.^그리고.$각 행의 선두와 말미에서 일치시킵니다(다만, 문자열 전체의 선두와 말미에서만 일치합니다).

Pattern.DOTALL또는(?s)는 Java에게 점이 줄 바꿈 문자에도 일치하도록 지시합니다.

둘째, 이 경우 regex가 실패하는 이유는matches()정규식이 문자열 전체와 일치할 것으로 예상하는 메서드 - 물론 이 메서드는 다음 문자가 남아 있기 때문에 작동하지 않습니다.(\\W)*(\\S)*일치합니다.

따라서 단순히 다음 문자열로 시작하는 문자열을 찾는다면User Comments:, regex 를 사용합니다.

^\s*User Comments:\s*(.*)

와 함께Pattern.DOTALL옵션:

Pattern regex = Pattern.compile("^\\s*User Comments:\\s+(.*)", Pattern.DOTALL);
Matcher regexMatcher = regex.matcher(subjectString);
if (regexMatcher.find()) {
    ResultString = regexMatcher.group(1);
} 

ResultString그 후 다음 텍스트가 포함됩니다.User Comments:

이것은 MULTILINE 플래그와는 관계가 없습니다.이러한 플래그가 표시되는 것은,find()그리고.matches()방법들. find()는, 타겟 문자열내의 어느 장소에서도 일치를 찾을 수 있는 경우에 성공합니다.matches()는 regex가 문자열 전체와 일치할 것으로 예상하고 있습니다.

Pattern p = Pattern.compile("xyz");

Matcher m = p.matcher("123xyzabc");
System.out.println(m.find());    // true
System.out.println(m.matches()); // false

Matcher m = p.matcher("xyz");
System.out.println(m.matches()); // true

더 나아가,MULTILINE네가 생각하는 그런 게 아니야많은 사람들은 대상 문자열에 줄바꿈이 포함되어 있는 경우, 즉 여러 개의 논리 행이 포함되어 있는 경우 플래그를 사용해야 한다고 속단하는 것 같습니다.SO에 관한 몇 가지 답변을 봤지만 사실 그 깃발이 하는 건 앵커들의 행동을 바꾸는 것뿐이에요^그리고.$.

보통.^타겟 스트링의 선두와 일치합니다.$맨 끝과 일치합니다(또는 맨 끝의 줄바꿈 앞이지만, 지금은 생략합니다).그러나 문자열에 줄바꿈이 포함되어 있는 경우,^그리고.$MULTILINE 플래그를 설정하여 문자열 전체의 시작과 끝뿐만 아니라 논리행의 시작과 끝에서도 일치시킵니다.

그러니 잊어버려MULTILINE , 동작만 기억하면 됩니다.^그리고.$닻을 올립니다. DOTALL모드는 원래 "single-line"이라고 불렸습니다(또한 Perl과 같은 일부 플레이버에서도 사용되고 있습니다).NET)는, 항상 같은 혼란을 초래해 왔습니다.이 경우 Java dev가 보다 알기 쉬운 이름을 사용한 것은 다행이지만, "멀티라인" 모드에 대한 합리적인 대체 방법은 없었습니다.

이 모든 광기가 시작된 Perl에서는 실수를 인정하고 Perl 6 정규식에서 "멀티라인"과 "싱글라인" 모드를 모두 없앴습니다.앞으로 20년 후에는 다른 나라들도 따라 했을지도 모른다.

str.matches(regex) 를 부리다 Pattern.matches(regex, str)한다.

true입력 시퀀스 전체가 이 매처 패턴과 일치하는 경우에만

반에 whereas whereas.matcher.find() 패턴과 일치하는 입력 시퀀스의 다음 시퀀스를 검색하여 반환하려고 합니다.

true입력 시퀀스의 후속이 이 매처 패턴과 일치하는 경우에만

따라서 regex에 문제가 있습니다.다음을 시도해 보십시오.

String test = "User Comments: This is \t a\ta \ntest\n\n message \n";

String pattern1 = "User Comments: [\\s\\S]*^test$[\\s\\S]*";
Pattern p = Pattern.compile(pattern1, Pattern.MULTILINE);
System.out.println(p.matcher(test).find());  //true

String pattern2 = "(?m)User Comments: [\\s\\S]*^test$[\\s\\S]*";
System.out.println(test.matches(pattern2));  //true

요대,는(\\W)*(\\S)*은 빈 합니다.「 regex 」 。*는 0 하며 실제 은 0입니다.User Comments: 두 번째 것은 시킬 수 없습니다.\\W 문자, 비단어 문자)와 합니다.[^a-zA-Z0-9_] 첫 글자는 '우리'입니다.T , , , , , , , , , , , , , , , , , , , , , , .

멀티라인 플래그는 와일드카드로 충분한 스트링 전체가 아닌 각 행에 패턴을 일치시키도록 regex에 지시합니다.

언급URL : https://stackoverflow.com/questions/3651725/match-multiline-text-using-regular-expression

반응형