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.