[javascript] 사용자 입력 문자열을 정규식으로 변환

HTML 및 JavaScript로 정규식 테스터를 설계하고 있습니다. 사용자는 정규식, 문자열을 입력하고 라디오 버튼을 통해 테스트하려는 기능 (예 : 검색, 일치, 바꾸기 등)을 선택하면 해당 함수가 지정된 인수로 실행될 때 결과가 표시됩니다. 당연히 추가 인수를 대체 할 수있는 추가 텍스트 상자가 있습니다.

내 문제는 사용자로부터 문자열을 가져 와서 정규 표현식으로 바꾸는 것입니다. 내가 //입력 한 정규 표현식 주위 에있을 필요가 없다고 말하면 gand 같은 플래그를 설정할 수 없습니다 i. 그래서 그들은 //표현식 주위 에가 있어야 하지만 어떻게 그 문자열을 정규식으로 변환 할 수 있습니까? 문자열이기 때문에 리터럴이 될 수 없으며의 문자열이 아니기 때문에 RegExp 생성자에 전달할 수 없습니다 //. 사용자 입력 문자열을 정규식으로 만드는 다른 방법이 있습니까? 정규식의 문자열과 플래그를로 구문 분석하고 //다른 방법으로 구성해야합니까? 문자열을 입력 한 다음 플래그를 별도로 입력해야합니까?



답변

RegExp 객체 생성자 를 사용하여 문자열 에서 정규식 을 만듭니다.

var re = new RegExp("a|b", "i");
// same as
var re = /a|b/i;


답변

var flags = inputstring.replace(/.*\/([gimy]*)$/, '$1');
var pattern = inputstring.replace(new RegExp('^/(.*?)/'+flags+'$'), '$1');
var regex = new RegExp(pattern, flags);

또는

var match = inputstring.match(new RegExp('^/(.*?)/([gimy]*)$'));
// sanity check here
var regex = new RegExp(match[1], match[2]);


답변

다음은 하나의 라이너입니다. str.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&')

escape-string-regexp NPM 모듈 에서 얻었습니다 .

그것을 시도 :

escapeStringRegExp.matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g;
function escapeStringRegExp(str) {
    return str.replace(escapeStringRegExp.matchOperatorsRe, '\\$&');
}

console.log(new RegExp(escapeStringRegExp('example.com')));
// => /example\.com/

플래그 지원 태그가 지정된 템플릿 리터럴 사용

function str2reg(flags = 'u') {
    return (...args) => new RegExp(escapeStringRegExp(evalTemplate(...args))
        , flags)
}

function evalTemplate(strings, ...values) {
    let i = 0
    return strings.reduce((str, string) => `${str}${string}${
        i < values.length ? values[i++] : ''}`, '')
}

console.log(str2reg()`example.com`)
// => /example\.com/u


답변

JavaScript RegExp 객체 생성자를 사용하십시오 .

var re = new RegExp("\\w+");
re.test("hello");

생성자에 플래그를 두 번째 문자열 인수로 전달할 수 있습니다. 자세한 내용은 설명서를 참조하십시오.


답변

필자의 경우 사용자 입력 somethimes는 구분 기호로 둘러싸여 있으며 때로는 그렇지 않습니다. 따라서 나는 다른 사건을 추가했다.

var regParts = inputstring.match(/^\/(.*?)\/([gim]*)$/);
if (regParts) {
    // the parsed pattern had delimiters and modifiers. handle them. 
    var regexp = new RegExp(regParts[1], regParts[2]);
} else {
    // we got pattern string without delimiters
    var regexp = new RegExp(inputstring);
}


답변

특수 플래그에 대해 별도의 확인란 또는 텍스트 필드를 추가하는 것이 좋습니다. 그렇게하면 사용자가를 추가 할 필요가 없다는 것이 분명합니다 //. 교체 할 경우 두 개의 텍스트 필드를 제공하십시오 . 이것은 당신의 인생을 훨씬 쉽게 만들 것입니다.

왜? 그렇지 않으면 일부 사용자는를 추가 //하고 다른 사용자는 추가 하지 않기 때문입니다. 그리고 일부는 구문 오류를 만듭니다. 그런 다음의를 제거한 후에 //는 사용자가 의도 한 것과 다른 문법적으로 유효한 정규식으로 끝나서 (사용자 관점에서) 이상한 동작이 발생할 수 있습니다.


답변

문자열이 유효하지 않거나 플래그 등을 포함하지 않는 경우에도 작동합니다.

function regExpFromString(q) {
  let flags = q.replace(/.*\/([gimuy]*)$/, '$1');
  if (flags === q) flags = '';
  let pattern = (flags ? q.replace(new RegExp('^/(.*?)/' + flags + '$'), '$1') : q);
  try { return new RegExp(pattern, flags); } catch (e) { return null; }
}

console.log(regExpFromString('\\bword\\b'));
console.log(regExpFromString('\/\\bword\\b\/gi'));