정규 표현식으로 여러 줄의 문자를 어떻게 일치 시키려면?

StackOverflow https://stackoverflow.com/questions/159118

  •  03-07-2019
  •  | 
  •  

문제

예를 들어,이 regex

(.*)<FooBar>

일치합니다 :

abcde<FooBar>

그러나 여러 줄에 걸쳐 어떻게 일치하도록하려면 어떻게해야합니까?

abcde
fghij<FooBar>
도움이 되었습니까?

해결책

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

/(.*)<FooBar>/s

그만큼 에스 결국에는 점이 일치하게됩니다 모두 Newlines를 포함한 캐릭터.

다른 팁

이 시도:

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

기본적으로 "모든 캐릭터 또는 신약"이 0 이상 반복되었다고 말합니다.

Eclipse 검색을 사용하는 경우 "DotAll"옵션을 만들 수 있습니다. 검색 문자열의 시작 부분에서 라인 구분 기호를 포함한 모든 문자와 "(? s)"를 추가하십시오. 예시:

(?s).*<FooBar>

문제는 할 수 있다는 것입니다 . 패턴 일치 어느 캐릭터? 대답은 엔진마다 다릅니다. 주요 차이점은 패턴이 POSIX 또는 비 POSIX Regex 라이브러리에 의해 사용되는지 여부입니다.

특별한 메모 : 그들은 정규 표현으로 간주되지는 않지만 . POSIX 기반 엔진과 동일한 숯과 일치합니다.

또 다른 메모 그리고 : . 기본적으로 모든 숯과 일치합니다 (데모): str = "abcde\n fghij<Foobar>"; expression = '(.*)<Foobar>*'; [tokens,matches] = regexp(str,expression,'tokens','match'); (tokens a abcde\n fghij 안건).

또한, 모든 것 'Regex Grammars 도트는 기본적으로 라인이 깨지는 것과 일치합니다. Boost의 ecmascript 문법을 regex_constants::no_mod_m (원천).

에 관해서 (POSIX 기반), 사용 n 옵션 (데모): select regexp_substr('abcde' || chr(10) ||' fghij<Foobar>', '(.*)<Foobar>', 1, 1, 'n', 1) as results from dual

POSIX 기반 엔진:

단순한 . 이미 라인 브레이크와 일치하고 수정자를 사용할 필요가 없습니다. (데모).

그만큼 (데모), (데모), (tre, base r 기본 엔진이있는 기본 엔진 perl=TRUE,베이스 r과 함께 perl=TRUE 또는 문자열/Stringi 패턴, 사용 (?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이 연속적인 Newlines를 사용하는 '단락 모드'를 활성화하고 활성화합니다.\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 사용자.

데모를 참조하십시오.

비 포스 기반 엔진:

  • - 사용 s 수정 자 PCRE_DOTALL MODIFIER: 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) 인라인 수정 자 (데모): m = re.search(r"(.*)<FooBar>", s, flags=re.S) (그리고 if m:, print(m.group(1)))
  • - 사용 Pattern.DOTALL 수정 자 (또는 인라인 (?s) 깃발) (데모): Pattern.compile("(.*)<FooBar>", Pattern.DOTALL)
  • - 사용 (?s) 패턴 내 수정 자 (데모): regex = /(?s)(.*)<FooBar>/
  • - 사용 (?s) 수정 자 (데모): "(?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>.
  • - 사용 /m 멀티 린 수정 자 (데모): s[/(.*)<Foobar>/m, 1]
  • - 인라인 수정자를 사용하십시오 (?s) 처음에는 (데모): re: = regexp.MustCompile(`(?s)(.*)<FooBar>`)
  • - 사용 dotMatchesLineSeparators 또는 (더 쉽게) 통과합니다 (?s) 패턴에 대한 인라인 수정 자 : let rx = "(?s)(.*)<Foobar>"
  • - Swift와 동일합니다. (?s) 가장 쉽게 작동하지만 여기에 방법이 있습니다 옵션을 사용할 수 있습니다: NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionDotMatchesLineSeparators error:&regexError];
  • , - 사용 (?s) 수정 자 (데모): "(?s)(.*)<Foobar>" (Google 스프레드 시트에서 =REGEXEXTRACT(A2,"(?s)(.*)<Foobar>"))

메모 (?s):

대부분의 비 포스 엔진에서 (?s) 인라인 수정 자 (또는 내장 플래그 옵션)를 사용하여 시행 할 수 있습니다. . 라인 브레이크와 일치합니다.

패턴의 시작 부분에 배치하면 (?s) 모든 바하비를 바꿉니다 . 패턴에서. 만약 (?s) 처음에는 어딘가에 배치됩니다 . 오른쪽에 위치한 영향을받습니다. ~하지 않는 한 이것은 파이썬으로 전달 된 패턴입니다 re. 파이썬에서 re, 에 대해 상관없이 (?s) 위치, 전체 패턴 . 영향을 받다. 그만큼 (?s) 효과가 중지됩니다 (?-s). 수정 된 그룹은 지정된 범위의 Regex 패턴에만 영향을 미치는 데 사용될 수 있습니다 (예 : Delim1(?s:.*?)\nDelim2.* 첫 번째를 만들 것입니다 .*? Newlines와 두 번째와 일치합니다 .* 나머지 라인 만 일치합니다).

posix note:

비록 검색 엔진에서 모든 문자와 일치합니다. [\s\S] / [\d\D] / [\w\W] 구조물을 사용할 수 있습니다.

Posix에서 [\s\S] Regex Escape 시퀀스는 브래킷 표현식 내부에서 지원되지 않기 때문에 Char (JavaScript 또는 Non-Posix 엔진에서와 같이)와 일치하지 않습니다. [\s\S] 단일 숯과 일치하는 브래킷 표현으로 구문 분석됩니다. \ 또는 s 또는 S.

JavaScript에서 사용하십시오 /[\S\s]*<Foobar>/. 원천

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

도트는 Newlines ( r n)를 제외한 모든 일치합니다. 따라서 모든 문자와 일치하는 s s를 사용하십시오.

~ 안에 루비 당신은 ''를 사용할 수 있습니다m'옵션 (멀티 린) :

/YOUR_REGEXP/m

보다 Regexp 문서 자세한 내용은 ruby-doc.org에서.

우리는 또한 사용할 수 있습니다

(.*?\n)*?

욕심없이 Newline을 포함한 모든 것을 일치시킵니다

이것은 새로운 라인을 선택적으로 만듭니다

(.*?|\n)*?

"." 일반적으로 라인 브레이크와 일치하지 않습니다. 대부분의 Regex 엔진을 사용하면 추가 할 수 있습니다 S-플래그 (또한 호출 DOTALL 그리고 SINGLELINE) 만들다 "." 또한 Newlines 와도 일치합니다. 그것이 실패하면, 당신은 같은 일을 할 수 있습니다 [\S\s].

Eclipse의 경우 다음에는 다음과 같은 표현을했습니다.

foo

Jadajada Bar "

일반 표현 :

Foo[\S\s]{1,10}.*Bar*
/(.*)<FooBar>/s

S는 DOT (.)를 캐리지 리턴과 일치하게합니다.

Java 기반 정규 표현식에서 사용할 수 있습니다 [\s\S]

주목하십시오 (.|\n)* (예를 들어)보다 덜 효율적일 수 있습니다. [\s\S]* (당신의 언어의 regexes가 그러한 도피를 지원하는 경우) 그리고 만드는 수정자를 지정하는 방법을 찾는 것보다. 또한 Newlines 와도 일치합니다. 또는 Posixy 대안과 같은 대안으로 갈 수 있습니다 [[:space:][:^space:]]*.

regexoptions.singleline을 사용하면 의미가 변경됩니다. Newlines를 포함합니다

regex.replace (Content, SearchText, Replacetext, RegeXoptions.singLeline);

해결책:

Pattern Modifier SU 사용은 PHP에서 원하는 매칭을 얻습니다.

예시:

preg_match('/(.*)/sU',$content,$match);

원천:

http://dreamluverz.com/developers-tools/regex-match-all-including-new-line http://php.net/manual/en/reference.pcre.pattern.modifiers.php

언어 내에서 사용하는 맥락에서, 정규 표현식은 줄이 아닌 문자열에 작용합니다. 따라서 입력 문자열에 여러 줄이 있다고 가정 할 때 정상적으로 Regex를 사용할 수 있어야합니다.

이 경우 주어진 regex는 전체 문자열과 일치합니다. "u003CFooBar> "존재합니다. Regex 구현의 세부 사항에 따라, $ 1 값 ("(.*) "에서 얻은 1 달러는"fghij "또는"abcde nfghij "가됩니다. 다른 구현에서는 일부 구현이 허용됩니다. "."가 Newline과 일치하는지 여부를 제어하여 선택을 제공합니다.

라인 기반 정규 표현식 사용은 일반적으로 EGREP와 같은 명령 줄에 대한 것입니다.

나는 같은 문제를 겪었고 아마도 가장 좋은 방법은 아니지만 작동했을 것입니다. 실제 경기를하기 전에 모든 라인 브레이크를 교체했습니다.

mystring= Regex.Replace(mystring, "\r\n", "")

나는 HTML을 조작하고 있으므로이 경우 라인 브레이크가 실제로 중요하지 않습니다.

위의 모든 제안을 행운없이 시도했습니다. .NET 3.5 FYI를 사용하고 있습니다.

JavaScript에서는 [^]*을 사용하여 라인 브레이크를 포함하여 0에서 무한 문자를 검색 할 수 있습니다.

$("#find_and_replace").click(function() {
  var text = $("#textarea").val();
  search_term = new RegExp("[^]*<Foobar>", "gi");;
  replace_term = "Replacement term";
  var new_text = text.replace(search_term, replace_term);
  $("#textarea").val(new_text);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button id="find_and_replace">Find and replace</button>
<br>
<textarea ID="textarea">abcde
fghij&lt;Foobar&gt;</textarea>

일반적으로 . 최신 라인과 일치하지 않으므로 시도하십시오 ((.|\n)*)<foobar>

Java의 특정 if 블록과 일치하고 싶었습니다.

   ...
   ...
   if(isTrue){
       doAction();

   }
...
...
}

regexp를 사용하는 경우

if \(isTrue(.|\n)*}

메소드 블록에 대한 닫는 버팀대가 포함되어 사용했습니다.

if \(!isTrue([^}.]|\n)*}

와일드 카드 경기에서 클로즈 브레이스를 제외합니다.

종종 우리는 기판 앞에 선을 가로 질러 몇 개의 키워드가 퍼지는 부분 문자열을 수정해야합니다. XML 요소를 고려하십시오.

<TASK>
  <UID>21</UID>
  <Name>Architectural design</Name>
  <PercentComplete>81</PercentComplete>
</TASK>

81을 다른 값으로 40으로 수정하고 싶다고 가정 해 .UID.21..UID., 그런 다음 포함 된 모든 문자를 건너 뜁니다 \n 까지 .PercentCompleted.. 정규 표현 패턴과 교체 사양은 다음과 같습니다.

String hw = new String("<TASK>\n  <UID>21</UID>\n  <Name>Architectural design</Name>\n  <PercentComplete>81</PercentComplete>\n</TASK>");
String pattern = new String ("(<UID>21</UID>)((.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
String replaceSpec = new String ("$1$2$440$6");
//note that the group (<PercentComplete>) is $4 and the group ((.|\n)*?) is $2.

String  iw = hw.replaceFirst(pattern, replaceSpec);
System.out.println(iw);

<TASK>
  <UID>21</UID>
  <Name>Architectural design</Name>
  <PercentComplete>40</PercentComplete>
</TASK>

하위 그룹 (.|\n) 아마도 누락 된 그룹 일 것입니다 $3. 우리가 그것을 캡처하지 않는다면 (?:.|\n) 그럼 $3 ~이다 (<PercentComplete>). 그래서 패턴과 replaceSpec 또한 다음과 같은 것일 수도 있습니다.

pattern = new String("(<UID>21</UID>)((?:.|\n)*?)(<PercentComplete>)(\\d+)(</PercentComplete>)");
replaceSpec = new String("$1$2$340$5")

그리고 교체는 이전과 같이 올바르게 작동합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top