여러 줄에 JavaScript 정규식을 사용하는 방법은 무엇입니까?


275
var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre.*?<\/pre>/gm );
alert(arr);     // null

줄 바꿈 문자에 걸쳐 있지만 PRE 블록을 선택하고 싶습니다. 나는 'm'플래그가 그렇게한다고 생각했다. 하지 않습니다.

게시하기 전에 여기 에서 답변을 찾았습니다 . 나는 JavaScript를 알고 있다고 생각하고 (3 권의 책을 읽고, 근무 시간을 보았습니다) 기존 솔루션이 없었기 때문에 어쨌든 게시 할 수 있습니다. 여기에 돌을 던져

따라서 해결책은 다음과 같습니다.

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[\s\S]*?<\/pre>/gm );
alert(arr);     // <pre>...</pre> :)

누구보다 덜 비밀스러운 방법이 있습니까?

편집 : 이것은 중복이지만 내 것보다 찾기가 어렵 기 때문에 제거하지 않습니다.

[^]"멀티 라인 도트"로 제안합니다 . 여전히 이해하지 못하는 것은 왜 [.\n]작동하지 않는 것입니다. 이것이 JavaScript의 슬픈 부분 중 하나 인 것 같습니다 ..


29
덜 비밀스러운 정규식? 본질적으로 불가능합니다.
Rubens Farias

BTW, 당신이해야 읽을 : "구문 분석 HTML을 다음 크 툴루 방법" codinghorror.com/blog/archives/001311.html
루벤스 파리 아스

1
링크는 이전 의견에서 변경되었습니다 : blog.codinghorror.com/parsing-html-the-cthulhu-way (5 년 후반)
dab

답변:


248

[.\n].내부에 특별한 의미가 없기 때문에 작동하지 않습니다 . []단지 문자 그대로를 의미합니다 .. (.|\n)"줄 바꿈을 포함한 모든 문자"를 지정하는 방법입니다. 모든 줄 바꿈을 일치 시키려면 \rWindows 및 클래식 Mac OS 스타일 줄 끝을 포함 하도록 추가해야합니다 (.|[\r\n]).

밖으로 그 회전은 다소 성가신뿐만 아니라 느린 (참조로 할 수 있습니다 자세한 내용은 KrisWebDev의 답변을 ), 더 나은 접근 방식으로, 모든 공백 문자와 모든 공백이 아닌 문자와 일치하는 것입니다, 그래서 [\s\S]모든 것을 일치하고있다 것이다, 빠르고 더 간단합니다.

일반적으로 실제 HTML 태그와 일치시키기 위해 정규 표현식을 사용해서는 안됩니다. 예를 들어 이유에 대한 자세한 내용은 다음 질문 을 참조하십시오.

대신 실제로 jQuery를 사용하여 필요한 태그를 검색하십시오 (jQuery를 사용하면 더 쉽게 할 수 있지만 항상 document.getElementsByTagName("pre")표준 DOM으로 할 수 있습니다 ). 내용과 일치 해야하는 경우 정규 표현식으로 해당 결과의 텍스트 내용을 검색하십시오. .


내가하고있는 일은 JavaScript를 사용하여 .wiki-> HTML 변환을 즉석에서 만드는 것입니다. 따라서 아직 DOM을 사용할 수 없습니다. 위키 파일은 대부분 자체 구문이지만, 필요한 경우 HTML 태그를 사용할 수 있습니다. DOM을 다루는 경우 조언이 매우 유효합니다. 감사. :)
akauppi

그럴 수 있지. HTML에 정규 표현식을 사용하려는 유효한 이유라고 생각하지만 HTML과 혼합 된 위키 구문에는 모든 종류의 재미있는 코너 케이스가있을 수 있습니다.
Brian Campbell

2
[\r\n]\ r \ n 시퀀스에 적용되면 먼저 \ r과 일치하고 \ n과 일치합니다. 시퀀스가 \ r \ n인지 또는 \ n인지에 관계없이 전체 시퀀스를 한 번에 일치 시키려면 패턴을 사용하십시오..|\r?\n
Eirik Birkeland

1
전체 여러 줄 문자열 을 일치 시키려면 욕심쟁이를 시도하십시오 [\s\S]+.
보아스

.내부 의미를 무시하는 JS 정규 표현식 구문 이 다른 정규 표현식 프레임 워크, 특히 .NET의 고급 프레임 워크 프레임 워크와 []다르다는 것을 후손에게 추가하고 싶습니다 . 사람들은 정규 표현식이 크로스 플랫폼이라고 가정 하지 마십시오 .
Mr. TA

330

여러 줄 일치 (.|[\r\n])대신 사용하지 마십시오 ..

여러 줄 일치 [\s\S]대신 사용하십시오.

또한 *?또는 +?대신에 *또는 수량 자를 사용하여 필요하지 않은 경우 탐욕을 피하십시오 +. 이는 성능에 큰 영향을 줄 수 있습니다.

내가 만든 벤치 마크를 참조하십시오 : http://jsperf.com/javascript-multiline-regexp-workarounds

Using [^]: fastest
Using [\s\S]: 0.83% slower
Using (.|\r|\n): 96% slower
Using (.|[\r\n]): 96% slower

주의 : 당신은 또한 사용할 수 [^]있지만 아래 주석에서 더 이상 사용되지 않습니다.


22
좋은 지적이지만 [^]어쨌든 사용하지 않는 것이 좋습니다 . 한편으로, JavaScript는 그 관용구를 지원하는 유일한 풍미이며, 심지어는 자주 사용되지도 않습니다 [\s\S]. 반면에, 대부분의 다른 맛은 ]먼저 그것을 나열하여 탈출 할 수 있습니다 . 즉, JavaScript에서는 [^][^]두 문자와 일치하지만 .NET 에서는 , 또는 이외의 문자 와 일치합니다 . ][^
Alan Moore

1
그것이 다른 캐릭터와 \S일치 \r하거나 \n다른 캐릭터와 어떻게 일치 하는지 어떻게 알 수 있습니까?
길리

3
자세한 내용은 이 질문 을 참조 하십시오. 이것은 모든 공백 문자 + 모든 공백 문자가 아닌 모든 문자와 일치하는 핵입니다. 정규 표현식 특수 문자 설명서 는 MDN 을 참조하십시오 .
KrisWebDev

4
어떤 이유가 선호하는 [\s\S]것처럼, 다른 사람을 통해 [\d\D]또는 [\w\W]?
Phrogz

1
욕심 많은 연산자에 대한 테스트가 준비되었음을 신속하게 알려 드리겠습니다. /<p>Can[^]*?<\/p>/와 동일한 콘텐츠와 일치하지 않습니다 /<p>Can[^]*<\/p>/. 욕심 많은 변형이 /<p>(?:[^<]|<(?!\/p>))*<\/p>/동일한 내용과 일치 하도록 변경되어야합니다 .
3limin4t0r

19

환경 및 Javascript (ECMAscript) 버전을 지정하지 않았으며이 게시물이 2009 년 이후 인 것을 알고 있습니다. 그러나 완전성을 위해 ECMA2018 릴리스에서는 이제 s플래그를 사용하여 .'\ n'과 일치 시킬 수 있습니다. https를 참조 하십시오. : //stackoverflow.com/a/36006948/141801

그러므로:

let s = 'I am a string\nover several\nlines.';
console.log('String: "' + s + '".');

let r = /string.*several.*lines/s; // Note 's' modifier
console.log('Match? ' + r.test(s); // 'test' returns true

이것은 최근 추가 된 것으로 현재 많은 환경에서 작동하지 않습니다. 예를 들어 Node v8.7.0은 인식하지 못하지만 Chromium에서는 작동하며 Typescript 테스트에서 사용하고 있습니다. 시간이 지남에 따라 더 주류가 될 것입니다.


1
이 크롬 (v67)에서 잘 작동하지만, 완전히 정규식 IE11 및 IEdge (V42)에 (또한 라인 별 작업 중지) 중단
freedomn-m

감사합니다 @ freedomn-m .. 매우 새로운 기능을 지원하지 않는 IE는 거의 놀랍지 않습니다 :) 그러나 그렇습니다. 사용하려는 시도가 작동하지 않는 이유를 '디버그'하려는 사람을 구하기 위해 어디에서 작동하지 않는지 언급 할 가치가 있습니다. 예상대로.
Neek

11

[.\n]도트 인 [](정규식 정의에 의해; 자바 스크립트에만 해당되지 않음)은 도트 문자를 의미 하기 때문에 작동하지 않습니다 . 대신 (.|\n)(또는 (.|[\n\r]))를 사용할 수 있습니다 .


24
[\s\S]개행을 포함하여 모든 항목을 일치시키는 가장 일반적인 JavaScript 관용구입니다. 눈에 더 쉽고 대체 기반 접근 방식보다 훨씬 효율적 (.|\n)입니다. (말 그대로 "모든 문자 의미 입니다 공백 또는 문자가 아닙니다 . 공백)
앨런 무어

2
당신 말이 맞지만 질문은 .및 에 관한 것이었고 \n왜 효과 [.\n]가 없는지 에 대한 질문이었습니다 . 질문에서 언급했듯이 [^]좋은 접근 방식입니다.
Y. Shoham

6

점을 줄 바꿈과 일치하지 않기 때문에 점 ( )을 또는 로 변경하여 (Chrome) 테스트하고 나 (둘 다 [^][^\0])에서 작동했습니다 (여기 참조 :.[^\0][^]http://www.regular-expressions.info/dot.html ).

var ss= "<pre>aaaa\nbbb\nccc</pre>ddd";
var arr= ss.match( /<pre[^\0]*?<\/pre>/gm );
alert(arr);     //Working


1
문제 [^\0]는 자바 스크립트 문자열에 null 문자가 허용 되어도 null 문자와 일치하지 않는다는 것입니다 ( 이 답변 참조 ).
Donald Duck

0

위에서 언급 한 예 외에도 대체 방법입니다.

^[\\w\\s]*$

\w단어와 \s공백은 어디에 있습니까?

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