development

문자열 변수를 사용하여 즉석에서 RegExps 만들기

big-blog 2020. 7. 1. 07:32
반응형

문자열 변수를 사용하여 즉석에서 RegExps 만들기


다음을 재사용 할 수있게 만들고 싶다고 가정 해 봅시다.

function replace_foo(target, replacement) {
   return target.replace("string_to_replace",replacement);
}

나는 이런 식으로 할 수 있습니다 :

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(string_to_replace,replacement);
}

문자열 리터럴을 사용하면 충분합니다. 그러나 정규식으로 조금 더 까다로워지고 싶다면 어떻게해야합니까? 예를 들어, 내가 모든 것을 대체하고 싶은 말은 하지만 string_to_replace . 본능적으로 다음과 같은 작업을 수행하여 위의 내용을 확장하려고합니다.

function replace_foo(target, string_to_replace, replacement) {
   return target.replace(/^string_to_replace/,replacement);
}

작동하지 않는 것 같습니다. 내 생각에 그것은 string_to_replace문자열을 나타내는 변수가 아니라 문자열 리터럴 이라고 생각 합니다. 문자열 변수를 사용하여 JavaScript 정규식을 즉석에서 만들 수 있습니까? 가능한 경우 다음과 같은 것이 좋습니다.

function replace_foo(target, string_to_replace, replacement) {
   var regex = "/^" + string_to_replace + "/";
   return target.replace(regex,replacement);
}

있다 new RegExp(string, flags)곳에 flags있습니다 g또는 i. 그래서

'GODzilla'.replace( new RegExp('god', 'i'), '' )

~에 평가하다

zilla

문자열 리터럴을 사용하면 충분합니다.

실제로는 아닙니다! 이 예는 첫 번째 발생 만 바꿉니다 string_to_replace. 보다 일반적으로 모든 발생을 바꾸려면 문자열을 전역 ( /.../g) RegExp 로 변환해야합니다 . new RegExp생성자를 사용하여 문자열 에서이 작업을 수행 할 수 있습니다 .

new RegExp(string_to_replace, 'g')

이것의 문제는 문자열 리터럴의 정규 표현식 특수 문자가 일반 문자가 아닌 특수한 방식으로 작동한다는 것입니다. 이를 해결하려면 백 슬래시-이스케이프 처리해야합니다. 불행히도이를 위해 내장 함수가 없으므로 사용할 수있는 기능은 다음과 같습니다.

function escapeRegExp(s) {
    return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}

또한 RegExp in을 사용 replace()하면 대체 문자열에도 특수 문자가 있습니다 $. $대체 텍스트에 리터럴 을 사용 하려면 이스케이프 처리해야합니다 !

function escapeSubstitute(s) {
    return s.replace(/\$/g, '$$$$');
}

( $그 자체가 대체 문자열이기 때문에 네 가지입니다 !)

이제 RegExp를 사용하여 전역 문자열 대체를 구현할 수 있습니다.

function replace_foo(target, string_to_replace, replacement) {
    var relit= escapeRegExp(string_to_replace);
    var sub= escapeSubstitute(replacement);
    var re= new RegExp(relit, 'g');
    return target.replace(re, sub);
}

얼마나 아파요? 운 좋게도 정규 표현식의 추가 부분이없는 직선 문자열 바꾸기 만하면 더 빠른 방법이 있습니다.

s.split(string_to_replace).join(replacement)

...그리고 그게 전부입니다. 이것은 일반적으로 이해되는 관용구입니다.

string_to_replace를 제외한 모든 것을 바꾸고 싶다고 말하십시오.

그 의미는 문자열과 일치하지 않는 모든 텍스트를 바꾸려는 것입니까? 부정이 아닌 문자열 시작 토큰을 의미 ^하기 때문에 확실히 대체 하지는 않습니다 ^. 캐릭터 그룹 ^의 부정입니다 []. 부정적인 전망도 (?!...)있지만 JScript에는 문제가 있으므로 일반적으로 피해야합니다.

You might try matching ‘everything up to’ the string, and using a function to discard any empty stretch between matching strings:

var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')')
return target.replace(re, function(match) {
    return match[1]===''? match[2] : replacement+match[2];
});

Here, again, a split might be simpler:

var parts= target.split(string_to_match);
for (var i= parts.length; i-->0;)
    if (parts[i]!=='')
        parts[i]= replacement;
return parts.join(string_to_match);

As the others have said, use new RegExp(pattern, flags) to do this. It is worth noting that you will be passing string literals into this constructor, so every backslash will have to be escaped. If, for instance you wanted your regex to match a backslash, you would need to say new RegExp('\\\\'), whereas the regex literal would only need to be /\\/. Depending on how you intend to use this, you should be wary of passing user input to such a function without adequate preprocessing (escaping special characters, etc.) Without this, your users may get some very unexpected results.


Yes you can.

https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

function replace_foo(target, string_to_replace, replacement) {
   var regex = new RegExp("^" + string_to_replace);
   return target.replace(regex, replacement);
}

I think I have very good example for highlight text in string (it finds not looking at register but highlighted using register)

function getHighlightedText(basicString, filterString) {

    if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString;

    return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'),
        function(match)
            {return "<mark>"+match+"</mark>"});

}

http://jsfiddle.net/cdbzL/1258/


A really simple solution to this is this:

function replace(target, string_to_replace, replacement) {
  return target.split(string_to_replace).join(replacement);
}

No need for Regexes at all

It also seems to be the fastest on modern browsers https://jsperf.com/replace-vs-split-join-vs-replaceall

참고URL : https://stackoverflow.com/questions/4371565/create-regexps-on-the-fly-using-string-variables

반응형