[regex] 정규식에서 여러 줄의 문자를 일치시키는 방법은 무엇입니까?

예를 들어이 정규식

(.*)<FooBar>

일치합니다 :

abcde<FooBar>

그러나 여러 줄에서 어떻게 일치합니까?

abcde
fghij<FooBar>



답변

언어에 따라 다르지만 정규식 패턴에 추가 할 수있는 수정자가 있어야합니다. PHP에서는 다음과 같습니다.

/(.*)<FooBar>/s

끝에 있는 s 는 점이 개행을 포함한 모든 문자 와 일치하게 합니다 .


답변

이 시도:

((.|\n)*)<FooBar>

기본적으로 “모든 문자 또는 줄 바꾸기”는 0 번 이상 반복되었습니다.


답변

문제는 어떤. 패턴과 일치 할 수 있다는 것 입니다 문자 있습니까? 답은 엔진마다 다릅니다. 주요 차이점은 패턴이 POSIX 또는 비 POSIX 정규식 라이브러리에서 사용되는지 여부입니다.

에 대한 특별 참고 사항 : 정규식으로 간주되지 않지만 .POSIX 기반 엔진과 동일한 문자와 일치합니다.

다른 메모 : .기본적으로 모든 문자와 일치합니다 ( demo ) : str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match');( 항목 tokens포함 abcde\n fghij).

또한 의 정규식 문법은 기본적으로 점이 줄 바꿈과 일치합니다. Boost의 ECMAScript 문법을 사용하면 regex_constants::no_mod_m( source ) 로이 기능을 끌 수 있습니다 .

에 관해서 (POSIX 기반) n옵션 ( demo )을 사용하십시오.select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual

POSIX 기반 엔진 :

단지 .이미 줄 바꿈과 일치하며 수정자를 사용할 필요가 없습니다.( 데모 ).

그만큼 ( 데모 )( 데모 )(TRE, no 기본 R 기본 엔진 perl=TRUE, stringr / stringi 패턴 이 perl=TRUE있거나 기본 R의 경우 인라인 수정자를 사용하십시오 ) ( demo )도 같은 방식으로 처리 하십시오. (?s).

그러나 대부분의 POSIX 기반 도구는 입력을 한 줄씩 처리합니다. 따라서 .범위에 속하지 않기 때문에 줄 바꿈과 일치하지 않습니다. 이를 무시하는 몇 가지 예는 다음과 같습니다.

  • -여러 가지 해결 방법이 있으며 가장 정확하지만 안전하지는 않습니다 sed 'H;1h;$!d;x; s/\(.*\)><Foobar>/\1/'( H;1h;$!d;x;파일을 메모리에 넣습니다). 전체 줄을 포함해야하는 경우 sed '/start_pattern/,/end_pattern/d' file(시작에서 제거하면 일치하는 줄이 포함 된 것으로 끝남) 또는 sed '/start_pattern/,/end_pattern/{{//!d;};}' file(일치하는 줄을 제외하고) 고려할 수 있습니다.
  • perl -0pe 's/(.*)<FooBar>/$1/gs' <<< "$str"( -0전체 파일을 메모리에 넣고,에 -p의해 제공된 스크립트를 적용한 후 파일을 인쇄합니다 -e). 을 사용 -000pe하면 파일이 문지르고 Perl이 연속 줄 바꿈 ( \n\n)을 레코드 구분 기호로 사용하는 ‘단락 모드’를 활성화 합니다.
  • grep -Poz '(?si)abc\K.*?(?=<Foobar>)' file. 여기에서 z파일 슬러 핑을 (?s)활성화하고, .패턴에 대해 DOTALL 모드를 활성화하고 , (?i)대소 문자를 구분하지 않는 모드를 활성화 \K하고, 지금까지 일치하는 텍스트를 생략하고 *?, 게으른 수량 자이며, (?=<Foobar>)이전 위치와 일치합니다 <Foobar>.
  • pcregrep -Mi "(?si)abc\K.*?(?=<Foobar>)" file( M여기서 파일 슬러 핑을 활성화합니다). 참고 pcregrep는 Mac OS grep사용자에게 좋은 솔루션입니다 .

데모를 참조하십시오 .

POSIX 기반이 아닌 엔진 :

  • s수정 자 PCRE_DOTALL 수정 자 사용 : preg_match('~(.*)<Foobar>~s', $s, $m)( 데모 )
  • – 사용 RegexOptions.Singleline플래그 ( 데모 ) :
    var result = Regex.Match(s, @"(.*)<Foobar>", RegexOptions.Singleline).Groups[1].Value;
    var result = Regex.Match(s, @"(?s)(.*)<Foobar>").Groups[1].Value;
  • (?s)인라인 옵션 사용 :$s = "abcde`nfghij<FooBar>"; $s -match "(?s)(.*)<Foobar>"; $matches[1]
  • s수정 자 (또는 (?s)시작시 인라인 버전) 사용 ( 데모 ) :/(.*)<FooBar>/s
  • – 플래그 re.DOTALL(또는 re.S) 또는 (?s)인라인 수정 자 ( demo )를 사용합니다 m = re.search(r"(.*)<FooBar>", s, flags=re.S)(그리고 if m:, print(m.group(1)))
  • Pattern.DOTALL수정 자 (또는 인라인 (?s)플래그) 사용 ( demo ) :Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
  • (?s)패턴 내 수정 자 사용 ( demo ) :regex = /(?s)(.*)<FooBar>/
  • (?s)수정 자 사용 ( demo ) :"(?s)(.*)<Foobar>".r.findAllIn("abcde\n fghij<Foobar>").matchData foreach { m => println(m.group(1)) }
  • -사용 [^]또는 해결 방법 [\d\D]/ [\w\W]/ [\s\S]( 데모 ) :s.match(/([\s\S]*)<FooBar>/)[1]
  • ( std::regex) 사용 [\s\S]또는 JS 해결 방법 ( 데모 ) :regex rex(R"(([\s\S]*)<FooBar>)");
  • -JavaScript에서와 동일한 방법을 사용하십시오 ([\s\S]*)<Foobar>. ( 참고 : 객체 의 MultiLine속성
    RegExp은 때로는 .줄 바꿈 을 통해 일치 시킬 수있는 옵션으로 잘못 간주되는 반면, 실제로 는 JS 정규 표현식에서와 같이 문자열이 아닌 줄의 시작 / 끝과 일치하도록 행동 ^$행동 만 변경합니다 ) 행동.)

  • /m -MULTILINE 수정 자 사용 ( demo ) :s[/(.*)<Foobar>/m, 1]

  • -기본 R PCRE 정규 표현식-사용 (?s): regmatches(x, regexec("(?s)(.*)<FooBar>",x, perl=TRUE))[[1]][2]( 데모 )
  • ICU 정규식 엔진으로 구동되는 in stringr/ stringiregex 기능은 다음을 사용합니다 (?s). stringr::str_match(x, "(?s)(.*)<FooBar>")[,2]( 데모 )
  • (?s)시작할 때 인라인 수정자를 사용하십시오 ( demo ) :re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
  • dotMatchesLineSeparators또는 (?s)인라인 수정자를 패턴에 전달하십시오 .let rx = "(?s)(.*)<Foobar>"
  • -Swift와 동일하며 (?s)가장 쉽게 작동하지만 다음은 옵션 사용 방법입니다 .NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern
    options:NSRegularExpressionDotMatchesLineSeparators error:&regexError];
  • , (?s)수정 자 사용 ( demo ) : "(?s)(.*)<Foobar>"(Google Spreadsheets에서 =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>"))

참고 사항(?s) :

POSIX가 아닌 대부분의 엔진에서 (?s)인라인 수정 자 (또는 임베디드 플래그 옵션)를 사용하여 .줄 바꿈을 일치 시킬 수 있습니다 .

패턴의 시작 부분에 배치되면 패턴 (?s)의 모든 바하 비어가 변경 .됩니다. 를 (?s)시작 후 어딘가에 배치 하면 패턴이 Python에 전달 되지 않는 한. 오른쪽에있는 것만 영향을받습니다 . Python에서는 위치에 관계없이 전체 패턴 이 영향을받습니다. 를 사용하여 효과를 중지 합니다. 수정 된 그룹은 지정된 범위의 정규 표현식 패턴에만 영향을 미치기 위해 사용될 수 있습니다 (예 : 개행 에서 첫 번째 일치를 만들고 두 번째 행은 나머지 행과 만 일치).rere(?s).(?s)(?-s)Delim1(?s:.*?)\nDelim2.*.*?.*

POSIX 참고 :

POSIX가 아닌 정규식 엔진에서는 모든 문자와 일치하도록 [\s\S]/ [\d\D]/ [\w\W]구문을 사용할 수 있습니다.

POSIX에서는 [\s\S]정규 표현식 이스케이프 시퀀스가 ​​대괄호 표현식 내에서 지원되지 않기 때문에 JavaScript 또는 POSIX 엔진이 아닌 다른 문자와 일치하지 않습니다. [\s\S]단일 문자와 일치하는 대괄호 표현식으로 구문 분석 \되거나s 또는 S.


답변

Eclipse 검색을 사용하는 경우 “DOTALL”옵션을 사용하여 ‘.’을 만들 수 있습니다. 줄 구분자를 포함한 모든 문자와 일치 : 검색 문자열의 시작 부분에 “(? s)”를 추가하십시오. 예:

(?s).*<FooBar>


답변

많은 정규식 방언에서 /[\S\s]*<Foobar>/원하는대로 할 것입니다. 출처


답변

([\s\S]*)<FooBar>

점은 개행을 제외한 모든 문자와 일치합니다 (\ r \ n). 따라서 모든 문자와 일치하는 \ s \ S를 사용하십시오.


답변

에서 루비 m‘옵션 (여러 줄)을 사용할 수 있습니다 .

/YOUR_REGEXP/m

자세한 내용 ruby-doc.org 의 Regexp 설명서 를 참조하십시오.