가능한 문자열 중에서 정규 표현식을 만들고 싶습니다.
var usersString = "Hello?!*`~World()[]";
var expression = new RegExp(RegExp.escape(usersString))
var matches = "Hello".match(expression);
이를위한 내장 된 방법이 있습니까? 그렇지 않다면 사람들은 무엇을 사용합니까? 루비있다 RegExp.escape
. 나는 내 자신을 쓸 필요가 없다고 느끼지 않습니다. 거기에 표준이 있어야합니다. 감사!
답변
위에 링크 된 기능이 충분하지 않습니다. 문자 그룹에서 범위에 사용되는 ^
또는 $
(문자열의 시작과 끝) 또는를 이스케이프하지 않습니다 -
.
이 기능을 사용하십시오 :
function escapeRegex(string) {
return string.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
언뜻보기에는 불필요하게 보일 수 있지만 이스케이프 -
(및 ^
)는 문자를 이스케이프하는 데 적합한 기능을 문자 클래스와 정규식 본문에 삽입하는 데 적합합니다.
이스케이프 /
기능은 이스케이프 문자가 나중에 평가하기 위해 JS 정규식 리터럴에서 사용되도록 이스케이프 문자에 적합합니다.
둘 중 어느 하나를 피할 수있는 단점이 없으므로 더 넓은 사용 사례를 다루기 위해 탈출하는 것이 좋습니다.
그리고 이것이 표준 JavaScript의 일부가 아니라는 것은 실망스러운 일입니다.
답변
사람이, lodash을 사용하기 위해 v3.0.0 이후 _.escapeRegExp의 기능이 내장에있다 :
_.escapeRegExp('[lodash](https://lodash.com/)');
// → '\[lodash\]\(https:\/\/lodash\.com\/\)'
그리고 전체 lodash 라이브러리가 필요하지 않은 경우 해당 기능 만 필요할 수 있습니다 !
답변
여기에서 대부분의 표현식은 단일 특정 사용 사례를 해결합니다.
괜찮습니다.하지만 “항상 작동”방식을 선호합니다.
function regExpEscape(literal_string) {
return literal_string.replace(/[-[\]{}()*+!<=:?.\/\\^$|#\s,]/g, '\\$&');
}
정규 표현식에서 다음 용도로 리터럴 문자열을 “완전히 이스케이프”합니다.
- 정규식에 삽입 예 :
new RegExp(regExpEscape(str))
- 문자 클래스에 삽입 예 :
new RegExp('[' + regExpEscape(str) + ']')
- 정수 카운트 지정자에 삽입 예 :
new RegExp('x{1,' + regExpEscape(str) + '}')
- 비 JavaScript 정규식 엔진에서 실행
다루는 특수 문자 :
-
: 문자 클래스에서 문자 범위를 만듭니다.[
/]
: 문자 클래스를 시작 / 종료합니다.{
/}
: 분자 지정자를 시작 / 종료합니다.(
/)
: 그룹을 시작 / 종료합니다.*
/+
/?
: 반복 유형을 지정합니다..
: 모든 문자와 일치합니다.\
: 문자를 이스케이프하고 엔터티를 시작합니다.^
: 일치 영역의 시작을 지정하고 문자 클래스에서 일치를 무효화합니다.$
: 일치 영역의 끝을 지정합니다.|
: 교대를 지정합니다.#
: 빈 공간 모드에서 주석을 지정합니다.\s
: 여유 공간 모드에서는 무시됩니다.,
: 분자 지정자에서 값을 구분합니다./
: 표현식을 시작하거나 종료합니다.:
: 특수 그룹 유형과 펄 스타일 문자 클래스의 일부를 완성합니다.!
: 폭이 0 인 그룹을 무효화합니다.<
/=
: 폭이 0 인 그룹 사양의 일부.
노트:
/
정규 표현의 풍미에 꼭 필요한 것은 아닙니다. 그러나 누군가 (shudder) 가 할 경우를 대비하여 보호합니다eval("/" + pattern + "/");
.,
문자열이 숫자 지정자에서 정수인 경우 자동 컴파일 오류 대신 RegExp 컴파일 오류가 올바르게 발생합니다.#
그리고\s
자바 스크립트에서 탈출 할 필요가 있지만, 많은 다른 맛을하지 않습니다. 정규식이 나중에 다른 프로그램으로 전달 될 경우에는 여기서 이스케이프됩니다.
JavaScript 정규식 엔진 기능에 추가 될 가능성에 대비하여 정규 표현식을 미래에 대비해야 할 경우 더 편집증을 사용하는 것이 좋습니다.
function regExpEscapeFuture(literal_string) {
return literal_string.replace(/[^A-Za-z0-9_]/g, '\\$&');
}
이 함수는 향후 정규 표현식 플레이버에서 구문에 사용되지 않도록 명시 적으로 보장 된 문자를 제외한 모든 문자를 이스케이프합니다.
진정으로 위생을 유지하려면 다음과 같은 경우를 고려하십시오.
var s = '';
new RegExp('(choice1|choice2|' + regExpEscape(s) + ')');
이것은 해야 하지 다른 맛을 자바 스크립트에서 잘 컴파일,하지만 것입니다. 다른 플레이버로 전달하려는 경우 다음과 같이 null 경우를 s === ''
독립적으로 확인해야합니다.
var s = '';
new RegExp('(choice1|choice2' + (s ? '|' + regExpEscape(s) : '') + ')');
답변
정규식에 대한 Mozilla 개발자 네트워크 안내서 는 다음과 같은 이스케이프 기능을 제공합니다.
function escapeRegExp(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}
답변
jQueryUI의 자동 완성 위젯 (버전 1.9.1)에서는 약간 다른 정규식 (6753 행)을 사용합니다. 다음은 @bobince 접근법과 결합 된 정규식입니다.
RegExp.escape = function( value ) {
return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
}
답변
영숫자가 아닌 모든 문자를 빠져 나가는 것을 막을 수있는 것은 없습니다 :
usersString.replace(/(?=\W)/g, '\\');
당신이 할 때 어느 정도의 가독성을 잃지 re.toString()
만 많은 단순성 (및 보안)을 얻습니다.
ECMA-262에 따르면, 한편으로, 정규 표현식 “구문 문자는”영숫자가 아닌 항상 결과가 안전하고, 이스케이프 시퀀스 (그런하다 \d
, \w
, \n
)는 항상 영숫자 같은 거짓 제어 이스케이프는 생성되지 않습니다 것을 .
답변
에서 RegExp.escape에 대한 ES7 제안이 https://github.com/benjamingr/RexExp.escape/ 에서 사용할 수있는 polyfill로, https://github.com/ljharb/regexp.escape는 .