정규식에서 변수를 어떻게 사용합니까?


1378

String.replaceAll()JavaScript 로 메소드 를 만들고 싶습니다 . 정규식을 사용하는 것이 가장 간결한 방법이라고 생각합니다. 그러나 정규식에 변수를 전달하는 방법을 알 수 없습니다. 이 작업을 이미 수행하여의 모든 인스턴스를 "B"로 바꿀 수 있습니다 "A".

"ABABAB".replace(/B/g, "A");

그러나 나는 이런 식으로하고 싶다 :

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

그러나 분명히 이것은 텍스트 만 대체합니다 "replaceThis"... 그래서이 변수를 정규식 문자열에 어떻게 전달합니까?


9
현재이 기능을 JavaScript에 추가하기 위해 노력하고 있으며 의견이 있으시면 토론에 참여하십시오.
Benjamin Gruenbaum 2016 년

답변:


1839

/regex/g구문 을 사용하는 대신 새 RegExp 객체를 생성 할 수 있습니다 .

var replace = "regex";
var re = new RegExp(replace,"g");

이런 식으로 정규식 객체를 동적으로 만들 수 있습니다. 그럼 당신은 할 것입니다 :

"mystring".replace(re, "newstring");

272
과 같은 표현식을 사용해야하는 경우 /\/word\:\w*$/백 슬래시를 이스케이프해야합니다 new RegExp( '\\/word\\:\\w*$' ).
Jonathan Swinney

2
@gravityboy ( ''+ myNumber) .replace (/ 10 / g, 'a')를 수행하거나 16 진수를 원한다면 parseInt ( ''+ myNumber, 16)를 사용하여 10 진수에서 16 진수로 변환 할 수 있습니다.
Eric Wendelin 2016 년

29
이 질문은 RegEx가 상수 문자열 교체에만 사용된다는 것을 암시합니다. 따라서 문자열에 RegEx 메타 문자가 포함되어 있으면 실패하므로 대답이 잘못되었습니다.
슬프게도이

16
변수를 전달하는 예는 이것이 좋은 대답이 될 것입니다. 나는 이것을 읽은 후에도 여전히 고투하고 있습니다.
Goose

3
@JonathanSwinney : /문자열에서 정규식을 만들면 특별한 의미가 없으므로 피할 필요가 없습니다. /\/word\:\w*$/해야new RegExp('/word\\:\\w*$')
데이비드 호르 바스에게

211

Eric Wendelin이 언급했듯이 다음과 같이 할 수 있습니다.

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

이 결과 "regex matching ."입니다. 그러나 str1이 인 경우 실패합니다 ".". 당신은 결과를 ~로 "pattern matching regex"대체 할 것으로 기대 "regex"하지만, ...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

이것은 "."문자열 이지만 RegExp 생성자에서 여전히 정규 표현식으로 해석되므로 줄 바꿈이 아닌 문자를 의미하며 문자열의 모든 문자를 의미합니다. 이를 위해 다음 기능이 유용 할 수 있습니다.

 RegExp.quote = function(str) {
     return str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
 };

그럼 당신은 할 수 있습니다 :

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

항복 "pattern matching regex".


4
대체 할 첫 번째 매개 변수는 일반 문자열 일 수 있으며 정규 표현식 일 필요는 없습니까? str1 = "."; alert ( "패턴 일치.". replace (str1, "string"));

@some : 물론입니다. 위의 예가 사소한 것이기 때문입니다. 예를 들어 일반 문자열과 결합 된 패턴을 검색하거나 교체해야하는 경우 str.match (new RegExp ( "https? : //"+ RegExp.escape (myDomainName)))를 수행하십시오. 이스케이프 함수가 내장되지 않음.
Gracenotes

(계속) 또한 명백한 JC Grubbs는 전체 교체가 필요했습니다. String.replace (String, String)로 전역 바꾸기를 구현하면 큰 입력의 경우 속도가 느릴 수 있습니다. 나는 단지 두 가지 솔루션이 버그가 있고 특정 입력에서 예기치 않은 실패 할 것이라고 말하고 있습니다.
Gracenotes

4
developer.mozilla.org/en-US/docs/JavaScript/Guide/… 는 유사한 기능을 제공하지만 제외 -하고 포함 =!:/합니다.
chbrown

8
올바른 용어는 "인용"이 아닌 "탈출"입니다. 그냥 BTW.
Lawrence Dol

118

"ABABAB".replace(/B/g, "A");

항상 그렇듯이 : 필요하지 않으면 정규식을 사용하지 마십시오. 간단한 문자열 바꾸기의 경우 관용구는 다음과 같습니다.

'ABABAB'.split('B').join('A')

그러면 Gracenotes의 답변에서 언급 된 인용 문제에 대해 걱정할 필요가 없습니다.


11
그리고 이것이 정규식보다 빠르다는 것을 측정 했습니까?
Mitar

3
이것은 특히 '.'와 같은 특수 정규식 문자와 일치해야 할 때 바람직합니다.
Krease

1
음 ... 분할하지 않습니다. RegExp도 가져옵니다. 그렇다면 동일한 문제가 발생하지 않습니까? 어쨌든 ... .split (). join ()은 두 가지 작업이기 때문에 일부 플랫폼에서는 속도가 느릴 수 있지만 .replace ()는 하나의 작업이며 최적화 될 수 있습니다.

5
@ PacMan-- : 모두 splitreplace문자열이나 중 하나를 취할 수 RegExp개체를. 문제 replace가있다 split하지 않습니다 당신이 문자열을 사용할 때 단 하나의 교체를 얻을 수 있다는 것입니다.
bobince 2016 년


38

모든 어커런스 ( g) 를 얻으려면 대소 문자를 구분하지 않고 ( i) 경계를 사용하여 다른 단어 ( \\b) 내의 단어가되지 않도록 경계를 사용하십시오 .

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

예:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.

감사합니다! ( rx템플릿 문자열을 통해 Emacs / 스타일 보간을 통해 명시 적으로 유일하게 답할 수 있습니다.)
sam boosalis

34

match 메소드 와 함께 변수를 사용하려는 사람 은 나를 위해 일했습니다.

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight


20
this.replace( new RegExp( replaceThis, 'g' ), withThis );

여분의 (& 무의미한) 변수를 만들지 않으므로이 대답이 마음에 듭니다.
Wick

14

정규식을 동적으로 작성하려는 경우 new RegExp(string)생성자 를 사용하는 것이 적절한 해결 방법입니다 . 생성자가 특수 문자를 문자 그대로 처리 하려면 해당 문자 를 이스케이프해야합니다. 가 내장되어있는 기능 위젯 jQuery를 UI 자동 완성 라고 $.ui.autocomplete.escapeRegex:

[...] 내장 $.ui.autocomplete.escapeRegex기능 을 사용할 수 있습니다 . 단일 문자열 인수를 사용하고 모든 정규식 문자를 이스케이프하여 결과를에 안전하게 전달합니다 new RegExp().

jQuery UI를 사용하는 경우 해당 함수를 사용하거나 소스에서 해당 정의 복사 할 수 있습니다 .

function escapeRegex( value ) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

그리고 이것을 다음과 같이 사용하십시오 :

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"

9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

도구로 테스트


5
String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}

다음과 같이 테스트하십시오.

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))

4

또 다른 replaceAll 구현이 있습니다.

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };

4

그리고 Steven Penny의 답변의 coffeescript 버전은 # 2 Google 결과이기 때문에 .... 커피가 많은 문자가 제거 된 자바 스크립트 일지라도 ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

그리고 내 특별한 경우에

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"

왜 다운 보트인가? coffeescript -IS- 고유 한 구문을 가진 자바 스크립트입니다.
keen

robot.name=hubot자바 스크립트가 아닙니다.
codepleb

3

동적으로 생성 된 RegExp을 만들 수 있지만 (이 질문에 대한 다른 응답에 따라) 비슷한 게시물 에서 내 의견을 반영합니다 . String.replace () 의 기능 양식 은 매우 유용하며 많은 경우에 대한 필요성을 줄입니다. 동적으로 생성 된 RegExp 객체. (슬래시 / [AZ] + / regexp 리터럴 형식을 사용하는 대신 RegExp 생성자에 대한 입력을 문자열로 표시해야하기 때문에 약간의 고통이 있습니다)


3

변수 / 별칭 / 함수를 정규식에 삽입해야 할 필요성을 충족시키기 위해 이것이 내가 생각해 낸 것입니다.

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

여기서 'oldre'는 변수를 삽입하려는 원래 정규 표현식이고 'xx'는 해당 변수 / 별칭 / 함수의 자리 표시 자이며 'yy'는 실제 변수 이름, 별명 또는 함수입니다.


2

$ 1이 당신과 함께 작동하지 않으면 이것을 사용할 수 있습니다

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");

1

항상 indexOf반복해서 사용할 수 있습니다 .

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

교체에 일치하는 항목이 포함되어 있으면 무한 루프에 빠지지 않습니다.


1

귀하의 솔루션은 다음과 같습니다.

변수를 정규식에 전달하십시오.

내가 구현 한 것은 바꿀 텍스트 필드에서 값을 가져 오는 것이고 다른 하나는 "바꾸기"텍스트 필드이며 변수의 텍스트 필드에서 값을 가져 와서 변수를 RegExp로 설정하는 것입니다 추가 교체 기능. 제 경우에는 Jquery를 사용하고 있으며 JavaScript만으로도 할 수 있습니다.

자바 스크립트 코드 :

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
  var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.

  var sRegExInput = new RegExp(replace, "g");    
  $("body").children().each(function() {
    $(this).html($(this).html().replace(sRegExInput,replace_with));
  });

이 코드는 버튼의 Onclick 이벤트에 있으며 호출하는 함수에 넣을 수 있습니다.

이제 교체 기능에서 변수를 전달할 수 있습니다.


replace_with 변수는 값 자체가 아닌 DOM 요소를 포함합니다
Ben Taliadoros

1

이 자체 호출 함수는 인덱스를 사용하여 replacerItems를 반복하고 각 패스마다 문자열에서 replacerItems [index]를 전체적으로 변경합니다.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'

0

이 답변들 중 어느 것도 나에게 분명하지 않았다. 결국 http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-function-of-javascript/ 에서 좋은 설명을 찾았습니다.

간단한 대답은 다음과 같습니다.

var search_term = new RegExp(search_term, "g");    
text = text.replace(search_term, replace_term);

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

$("button").click(function() {
  Find_and_replace("Lorem", "Chocolate");
  Find_and_replace("ipsum", "ice-cream");
});

function Find_and_replace(search_term, replace_term) {
  text = $("textbox").html();
  var search_term = new RegExp(search_term, "g");
  text = text.replace(search_term, replace_term);
  $("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>


1
클로저 변수를 덮어 쓰고 있으므로 var여기서 사용할 필요가 없습니다 . 또한, 전달하는 경우 \b또는 \1이 휴식 것입니다.
CyberAP

0

정규 표현식이없는 다중 바꾸기의 경우 다음을 수행했습니다.

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

솔루션의 중요한 부분은 여기에서 발견되었습니다.

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