자바 스크립트 교체 / 정규식


113

이 기능이 주어지면 :

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(pattern, value);
        }

    };

    return repeater;

};

어떻게해야합니까 this.markup.replace()세계적으로 대체? 여기에 문제가 있습니다. 다음과 같이 사용하면 :

alert(new Repeater("$TEST_ONE $TEST_ONE").replace("$TEST_ONE", "foobar").markup);

경고의 값은 "foobar $ TEST_ONE"입니다.

Repeater다음으로 변경 하면 Chrome에서 아무것도 대체되지 않습니다.

function Repeater(template) {

    var repeater = {

        markup: template,

        replace: function(pattern, value) {
            this.markup = this.markup.replace(new RegExp(pattern, "gm"), value);
        }

    };

    return repeater;

};

... 알림은 $TEST_ONE $TEST_ONE입니다.

답변:


147

RegExp 문자를 이중으로 이스케이프해야합니다 (문자열의 슬래시에 대해 한 번, regexp에 대해 한 번) :

  "$TESTONE $TESTONE".replace( new RegExp("\\$TESTONE","gm"),"foo")

그렇지 않으면 줄의 끝과 'TESTONE'(찾지 못함)을 찾습니다.

개인적으로 저는 이런 이유로 문자열을 사용하여 정규 표현식을 구축하는 것을 좋아하지 않습니다. 필요한 탈출 수준에 따라 술을 마실 수 있습니다. 나는 다른 사람들이 정규식을 작성할 때 다르게 느끼고 술을 좋아한다고 확신합니다.


그러나 replace ()는 정규식을 변수로받습니다.
핵심

8
@Chris- /pattern/또는 을 사용하면 차이가 없다고 생각합니다 new RegExp("pattern").
harto

@seth, 귀하의 답변은 작동하지만 OP의 코드에 대한 솔루션을 제공하지 않습니다. OP의 코드를 어떻게 호출해야합니까?
Black

82

패턴 해석 측면에서는 다음 형식간에 차이가 없습니다.

  • /pattern/
  • new RegExp("pattern")

replace메서드를 사용하여 리터럴 문자열을 바꾸고 싶다면 정규 표현식 대신 문자열을 replace.

그렇지 않으면 패턴에서 먼저 정규식 특수 문자를 이스케이프해야합니다.

function reEscape(s) {
    return s.replace(/([.*+?^$|(){}\[\]])/mg, "\\$1");
}

// ...

var re = new RegExp(reEscape(pattern), "mg");
this.markup = this.markup.replace(re, value);

12
/ pattern /이 new RegExp ( "pattern")와 동일하다는 사실을 전에는 몰랐습니다. 정말 도움이되었습니다!
Nik Sumeiko

1
블랙리스트 대신 화이트리스트를 사용하지 않을 이유가 있습니까? 예 : s.replace (/ (\ W) / g, '\\ $ 1')
greg.kindel

1
나열된 첫 번째 양식이 더 좋습니다. 키워드 를 사용하지 않는 것이 좋습니다 .
Druska 2013

2
정규식 리터럴 (/ regex /)이 RegExp ( "regex")와 동일하다고 말하는 것은 정확하지 않습니다. 정규식 리터럴에서 역솔 리더스 ( '\')는 정규식의 일부가되기 위해 이스케이프 ( '\\') 할 필요가 없습니다. 또한 정규식 리터럴은 함수가 실행될 때마다가 아니라 스크립트가 구문 분석 될 때 컴파일 될 수 있습니다. 역솔 리더스를 일치시키기 위해 / \\ / 또는 RexExp ( "\\\\")를 쓸 수 있습니다.
John

31

정규식 패턴에는 g 수정자가 있어야합니다.

var pattern = /[somepattern]+/g;

끝에 g가 있습니다. 대체자에게 전역 대체를 수행하도록 지시합니다.

또한 위와 같이 패턴을 구성 할 수있는 RegExp 개체를 사용할 필요가 없습니다. 패턴 예 :

var pattern = /[0-9a-zA-Z]+/g;

패턴은 항상 양쪽에 /로 둘러싸여 있습니다.-최종 / 뒤에 수정자가 있으며 g 수정자는 전역입니다.

편집 : 패턴이 변수 인 경우 왜 중요합니까? 귀하의 경우에는 다음과 같이 작동합니다 (패턴은 여전히 ​​변수입니다).

var pattern = /[0-9a-zA-Z]+/g;
repeater.replace(pattern, "1234abc");

그러나 교체 기능을 다음과 같이 변경해야합니다.

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