JavaScript 정규식 여러 줄 플래그가 작동하지 않습니다


265

HTML에서 문자열을 가져 오기 위해 정규식을 작성했지만 여러 줄 플래그가 작동하지 않는 것 같습니다.

이것은 내 패턴이며 텍스트를 h1태그 로 가져 오려고합니다.

var pattern= /<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/mi
m = html.search(pattern);
return m[1];

테스트 할 문자열을 만들었습니다. 문자열에 "\ n"이 포함 된 경우 결과는 항상 null입니다. 모든 "\ n"을 제거하면 /m플래그 유무에 관계없이 올바른 결과를 얻었습니다 .

내 정규식에 어떤 문제가 있습니까?


14
HTML을 구문 분석하기 위해 정규식을 사용하지 마십시오. HTML은 정규 언어가 아닙니다. HTML 파서를 사용하십시오. DOM. 또한 훨씬 간단합니다.
— Svante

여러 줄이 아닌 DOTALL을 찾고 있습니다.
— Vanuan

참고 자바 스크립트가 곧있을 것이다dotAll 수정을 당신이 할 수 있도록 /.../s하고 점은 새로운 라인을 일치합니다. 2017 년 7 월 현재 Chrome에서 플래그 뒤에 있습니다.

답변:


609

dotall 수정 자라고/.../s 도 하는 수정자를 찾고 있습니다. 또한 점이 줄 바꿈과 일치하도록 강제 설정하지만 기본적으로 는 그렇지 않습니다 ..

나쁜 소식은 JavaScript에 존재 하지 않는다는 것입니다 (ES2018 기준으로 아래 참조) . 좋은 소식은 다음과 같이 문자 클래스 (예 \s:)와 해당 부정 ( \S)을 함께 사용하여 문제를 해결할 수 있다는 것입니다 .

[\s\S]

따라서 귀하의 경우 정규식은 다음과 같습니다.

/<div class="box-content-5">[\s\S]*<h1>([^<]+?)<\/h1>/i

ES2018로, 자바 스크립트가 지원 s때문에 당신이 그것을 쓴 정규 표현식이 될 수있는 현대적인 환경에서, (DOTALL) 플래그를하지만과 s끝 플래그 (이 아니라 m, m변화하는 방법 ^과 $작업,하지 .) :

/<div class="box-content-5">.*<h1>([^<]+?)<\/h1>/is

5
@simo 공백 문자 또는 공백 문자가 아닌 문자를 일치시켜 문자를 효과적으로 일치시킵니다. 그것은 .같지만 공백도 일치 ( \s)는 일치한다는 것을 의미합니다 \n( .JavaScript에서 수행하지 않거나 s플래그 와 관련이 있음 ).
— alex

1
이 답변은 "Modifiers"아래 의 Stack Overflow Regular Expression FAQ 에 추가되었습니다 .
— aliteralmind

40
MDN에 따르면 [^]JavaScript에서 줄 바꿈을 포함한 모든 문자와 일치하도록 작동합니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
— Dan Allen

6
성능 문제의 경우 탐욕을 피하기 위해 *?대신 정량 자를 사용하는 것이 좋습니다 *. 이것은이 끼지 않도록합니다 마지막으로 당신이 원하는 아마 그리고 정규 표현식은 이미 전에 그것을 발견 한 경우에도 문자열이 끝날 때까지 <H1>을 찾아 나갈 것 같은 그 효율적이지의 : <H1> 문서의.
— KrisWebDev

9
[^] 버전은 정규식 컴파일러에서 더 쉽고 더 간결합니다.
— Erik Corry 2019

21

당신은 원하는 s분명히 자바 스크립트에 존재하지 않는 (DOTALL) 수정을 - 당신은 대체 할 수 .와 [\ S \ S] @molf에 의해 제안. m(다중) 수정 차종 ^ 및 $ 일치하는 라인이 아닌 전체 문자열.


4
/ s "수정자가 멀티 라인 모드와 달리 싱글 라인 모드를 설정한다고 덧붙일 수 있습니다. +1
— Cerebrus

9 년 후 JavaScript는 이제 s플래그 (ES2018)를 갖습니다. :-)
— TJ Crowder

12

[\s\S]nodejs 6.11.3에서 작동하지 않았습니다. 에 기초 정규식 문서 , 그것은 사용하기 말합니다 [^]나를 위해 작업을 수행한다.

(점, 소수점)은 줄 종결자를 제외한 모든 단일 문자 (\ n, \ r, \ u2028 또는 \ u2029)와 일치합니다.

문자 집합 내에서 점은 특별한 의미를 잃고 리터럴 점과 일치합니다.

m 멀티 라인 플래그는 도트 동작을 변경하지 않습니다. 따라서 여러 줄의 패턴을 일치시키기 위해 문자 집합 [^]을 사용할 수 있습니다 (물론 이전 버전의 IE를 의미하지 않는 경우), 개행을 포함한 모든 문자와 일치합니다.

예를 들면 다음과 같습니다.

/This is on line 1[^]*?This is on line 3/m

어디 *? [^]가 0 회 이상있는 욕심없는 잡입니다.


1
궁금해하는 사람들을 위해 [^]이 이중 부정과 같다 : 의미 "모든 문자와 일치 하지 이에 빈 목록" 하고 말에 내려 오는, 그래서 "모든 문자와 일치"를 .
— trincot


0

여러 줄 문자열을 "\ n"으로 나누고 원래 문자열의 분할을 연결하는 것이 더 좋으며 한 줄로되어 조작하기 쉽다는 것이 좋습니다.

<textarea class="form-control" name="Body" rows="12" data-rule="required" 
                  title='@("Your feedback ".Label())'
                  placeholder='@("Your Feedback here!".Label())' data-val-required='@("Feedback is required".Label())'
                  pattern="^[0-9a-zA-Z ,;/?.\s_-]{3,600}$" data-val="true" required></textarea>


$( document ).ready( function() {
  var errorMessage = "Please match the requested format.";
  var firstVisit = false;

  $( this ).find( "textarea" ).on( "input change propertychange", function() {

    var pattern = $(this).attr( "pattern" );
    var element = $( this );

    if(typeof pattern !== typeof undefined && pattern !== false)
    {
      var ptr = pattern.replace(/^\^|\$$/g, '');
      var patternRegex = new RegExp('^' + pattern.replace(/^\^|\$$/g, '') + '$', 'gm');     

      var ks = "";
      $.each($( this ).val().split("\n"), function( index, value ){
        console.log(index + "-" + value);
        ks += " " + value;
      });      
      //console.log(ks);

      hasError = !ks.match( patternRegex );
      //debugger;

      if ( typeof this.setCustomValidity === "function") 
      {
        this.setCustomValidity( hasError ? errorMessage : "" );
      } 
      else 
      {
        $( this ).toggleClass( "invalid", !!hasError );
        $( this ).toggleClass( "valid", !hasError );

        if ( hasError ) 
        {
          $( this ).attr( "title", errorMessage );
        } 
        else
        {
          $( this ).removeAttr( "title" );
        }
      }
    }

  });
});
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.