정규식에서 어떤 특수 문자를 이스케이프해야합니까?


389

()[]{}|많은 정규 표현식을 구현할 때 ' ' 와 같은 특수 문자를 피해야한다면 항상 추측하려고 노력하는 데 지쳤습니다 .

예를 들어 Python, sed, grep, awk, Perl, rename, Apache, find 등이 다릅니다. 특수 문자를 피해야 할 때와 그렇지 않아야 할 때를 알려주는 규칙 세트가 있습니까? PCRE, POSIX 또는 확장 정규 표현식과 같은 정규 표현식 유형에 의존합니까?


4
좋은 정규식 라이브러리에는 " escape()" 와 같은 기능 이있어 임의의 문자열을 정규식 부분으로 사용할 수 있습니다.
ivan_pozdeev

2
gskinner.com/RegExr (무료) 와 같은 온라인 정규식 검사기를 사용할 수 있습니다 . (입력 한 다음 정규 표현식 위에 마우스를 올려
놓으십시오

2
영숫자가 아닌 문자를 모두 이스케이프하십시오. 기간.
Salman von Abbas

2
이 질문은 "기타"아래 의 스택 오버플로 정규 표현식 FAQ 에 추가되었습니다 .
aliteralmind

1
이 질문은 "이스케이프 시퀀스"아래 의 스택 오버플로 정규 표현식 FAQ 에 추가되었습니다 .
aliteralmind

답변:


365

어떤 캐릭터를 사용해야하고 실제로 탈출하지 않아야하는 캐릭터는 작업중인 정규 표현식에 따라 다릅니다.

PCRE 및 대부분의 다른 소위 Perl 호환 특징의 경우 다음 외부 문자 클래스를 피하십시오.

.^$*+?()[{\|

그리고 이러한 내부 캐릭터 클래스 :

^-]\

POSIX 확장 정규 표현식 (ERE)의 경우 다음 외부 문자 클래스 (PCRE와 동일)를 이스케이프하십시오.

.^$*+?()[{\|

POSIX ERE에서 다른 문자를 이스케이프 처리하면 오류가 발생합니다.

문자 클래스 내에서 백 슬래시는 POSIX 정규식의 리터럴 문자입니다. 당신은 아무것도 탈출하는 데 사용할 수 없습니다. 문자 클래스 메타 문자를 리터럴로 포함하려면 "영리한 배치"를 사용해야합니다. 문자 클래스의 시작과 끝을 제외한 ^를 문자 클래스의 시작 또는 끝에-를 넣어 문자 그대로 일치시킵니다. 예를 들면 다음과 같습니다.

[]^-]

POSIX 기본 정규 표현식 (BRE)에서 다음은 의미를 억제하기 위해 이스케이프해야하는 메타 문자입니다.

.^$*[\

BRE에서 괄호와 중괄호를 이스케이프하면 이스케이프 처리되지 않은 버전이 ERE에서 특별한 의미를 갖습니다. 일부 구현 (예 : GNU)도 이스케이프 할 때 \?와 같은 다른 문자에 특별한 의미를 부여합니다. 그리고 +. . ^ $ * () {} 이외의 문자를 이스케이프 처리하는 것은 일반적으로 BRE의 오류입니다.

문자 클래스 내에서 BRE는 ERE와 동일한 규칙을 따릅니다.

이 모든 것이 머리를 돌리면 RegexBuddy 사본을 가져옵니다 . 작성 탭에서 토큰 삽입을 클릭 한 후 리터럴을 클릭하십시오. RegexBuddy는 필요에 따라 이스케이프를 추가합니다.


1
그것은 당신이 "/"를 잊어 버렸고, 그것은 또한 수업 밖에서 탈출해야합니다.
jackthehipster

11
/는 내가 언급 한 정규 표현식 맛의 메타 문자가 아니므로 정규 표현식 구문에서 이스케이프를 요구하지 않습니다. 정규 표현식은 그 언어의 문자열이나 정규 표현식 서식 규칙이 필요할 수 있습니다, 프로그래밍 언어의 문자 그대로 인용하는 경우 /"또는 '\ '이스케이프, 심지어 요구할 수있다`이중으로 탈출한다.
Jan Goyvaerts

2
콜론, ":"은 어떻습니까? 캐릭터 클래스와 외부에서 탈출해야합니까? en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions에 따르면 "PCRE에는 일관된 이스케이프 규칙이 있습니다. 영숫자가 아닌 문자는 문자 값 [...]을 의미하기 위해 이스케이프 처리 될 수 있습니다"
nicolallias

4
탈출해야 할 수도 있습니다 탈출해야합니다. PCRE 구문은 리터럴 콜론을 이스케이프 할 필요가 없으므로 리터럴 콜론을 이스케이프 처리하면 정규식을 읽기가 더 어려워집니다.
Jan Goyvaerts

1
비 POSIX ERE (Tcl에 의해 구현 된 것이기 때문에 가장 자주 사용하는 것)의 경우 다른 것을 탈출해도 오류가 발생하지 않습니다.
slebetman

61

최신 RegEx 맛 (PCRE)

C, C ++, Delphi, EditPad, Java, JavaScript, Perl, PHP (preg), PostgreSQL, PowerGREP, PowerShell, Python, REALbasic, Real Studio, Ruby, TCL, VB.Net, VBScript, wxWidgets, XML 스키마, Xojo, XRegExp.
PCRE 호환성은 다를 수 있습니다

    어딘가에: . ^ $ * + - ? ( ) [ ] { } \ |


레거시 RegEx 맛 (BRE / ERE)

awk, ed, egrep, emacs, GNUlib, grep, PHP (ereg), MySQL, Oracle, R, sed를 포함합니다.
PCRE 지원은 이후 버전 또는 확장을 사용하여 활성화 될 수 있습니다

ERE / awk / egrep / emacs

    캐릭터 클래스 외부 : 캐릭터 클래스 . ^ $ * + ? ( ) [ { } \ |
    내부 :^ - [ ]

BRE / ed / grep / sed

    문자 클래스 외부 : 문자 클래스 . ^ $ * [ \
    내부 : ^ - [ ]
    리터럴의 경우 이스케이프하지 마십시오. + ? ( ) { } |
    표준 정규식 동작의 경우 이스케이프합니다.\+ \? \( \) \{ \} \|


노트

  • 특정 캐릭터에 대해 잘 모르면 다음과 같이 벗어날 수 있습니다. \xFF
  • 영숫자 문자는 백 슬래시로 이스케이프 할 수 없습니다
  • 임의의 기호는 PCRE에서 백 슬래시로 이스케이프 할 수 있지만 BRE / ERE는 이스케이프 할 수 없습니다 (필요한 경우에만 이스케이프해야 함). PCRE의 ] -경우 문자 클래스 내에서만 이스케이프해야하지만 단순성을 위해 단일 목록으로 유지했습니다.
  • 인용 표현 문자열은 문자 탈출 주변의 인용문이 있어야하며, 종종 백 슬래시 두 배로 업 (같은 "(\")(/)(\\.)"/(")(\/)(\.)/자바 스크립트)
  • 이스케이프 외에도, 다른 정규식 구현은 다른 수정 자, 문자 클래스, 앵커, 수량 자 및 기타 기능을 지원할 수 있습니다. 자세한 내용은 체크 아웃 regular-expressions.info , 또는 사용 regex101.com를 당신의 표현이 살고 테스트

1
답변에는 다음을 포함하여 많은 오류가 있습니다. "현대"맛은 문자 클래스 외부에서 필요로 -하거나 ]탈출 하지 않습니다 . POSIX (BRE / ERE)에는 문자 클래스 내에 이스케이프 문자가 없습니다. 델파이 RTL의 정규 표현식은 실제로 PCRE를 기반으로합니다. Python, Ruby 및 XML에는 POSIX 특징보다 PCRE에 더 가까운 고유 한 특징이 있습니다.
Jan Goyvaerts

1
@JanGoyvaerts 수정 해 주셔서 감사합니다. 언급 한 맛은 실제로 PCRE에 더 가깝습니다. 탈출에 관해서는, 나는 단순성을 위해 그것들을 그렇게 유지했다. 몇 가지 예외를 넘어 모든 곳에서 탈출하는 것이 더 쉽습니다. 고급 사용자는 몇 가지 백 슬래시를 피하기 위해 무슨 일이 일어 났는지 알 수 있습니다. 어쨌든, 나는이 답변 중 일부를 희망적으로 설명하는 몇 가지 설명으로 답변을 업데이트했습니다.
Beejor

22

불행히도 사용중인 언어에 따라 다르기 때문에 실제로 일련의 이스케이프 코드가 없습니다.

그러나, 같은 페이지를 유지 정규 표현식 도구 페이지 또는이 정규 표현식 쪽지은 신속하게 필터의 일을 당신을 돕기 위해 먼 길을 갈 수 있습니다.


1
Addedbytes 치트 시트가 과도하게 단순화되었으며 눈부신 오류가 있습니다. 예를 들어, 말한다 \<\>부스트 정규식 라이브러리 만 (AFAIK)에 해당하는 단어 경계이다. 그러나 다른 곳에서 말한다 <>메타 문자가 있고 (도주해야 \<하고 \>어떤 맛에, 말 그대로 어떤 사실이 아니다 그들을 일치)
앨런 무어

5

불행히도 (and \ ()와 같은 의미는 Emacs 스타일 정규 표현식과 대부분의 다른 스타일 사이에서 바뀝니다.

그래서 당신은 실제로 어떤 스타일을 인용하려고하는지 알아야합니다.


5

POSIX는 기본 정규 표현식 (BRE) 및 확장 정규 표현식 (ERE)과 같은 정규 표현식의 여러 변형을 인식합니다. 그리고 POSIX에서 표준화 한 유틸리티의 역사적 구현으로 인해 단점이 있습니다.

어떤 표기법을 사용할 때 또는 주어진 명령이 어떤 표기법을 사용하는지에 대한 간단한 규칙은 없습니다.

Jeff Friedl의 Mastering Regular Expressions 책을 확인하십시오 .


4

실제로는 없습니다. 약 절반 정도의 서로 다른 정규 표현식 구문이 있습니다. 그들은 일반적으로 Perl, EMACS / GNU 및 AT & T로 내려 오는 것처럼 보이지만 항상 놀라고 있습니다.


4

목록에있는 문자로 간단한 이스케이프를 할 수없는 경우가 있습니다. 예를 들어, 괄호를 이스케이프하기 위해 백 슬래시를 사용하는 것은 sed의 대체 문자열 왼쪽에서 작동하지 않습니다.

sed -e 's/foo\(bar/something_else/'

대신 간단한 문자 클래스 정의를 사용하는 경향이 있으므로 위의 표현식은

sed -e 's/foo[(]bar/something_else/'

나는 대부분의 정규 표현식 구현에서 작동합니다.

BTW 문자 클래스는 꽤 ​​바닐라 정규 표현식 구성 요소이므로 정규 표현식에서 이스케이프 문자가 필요한 대부분의 상황에서 작동하는 경향이 있습니다.

편집 : 아래 의견 후에, 정규식 평가의 동작을 볼 때 유한 상태 오토마타와 비 유한 상태 오토마타의 차이점을 고려해야한다는 사실을 언급했다고 생각했습니다.

정규 표현식에 대한 장인 "유효한 볼 북"(일명 유효 표현식 (일명 Amazon 링크 ))을보고 정규 표현식 엔진 평가 유형의 차이를 느끼고 싶을 수 있습니다.

모든 세계가 PCRE는 아닙니다!

어쨌든 정규 표현식은 SNOBOL에 비해 너무 어색합니다 ! 이제 흥미로운 프로그래밍 과정이었다! Simula에 있는 것과 함께 .

70 년대 후반 UNSW에서 공부하는 기쁨! (-:


'sed'는 평범한 '('는 특별하지 않지만 '\ ('은 특별합니다. 반면에 PCRE는 의미를 반대로 바꾸는 명령이므로 '('은 특별하지만 '\ ('은 아닙니다)입니다. OP가 요구하고있다
Jonathan Leffler 08:12,

sed는 가장 원시적 인 정규식 평가 세트 중 하나를 사용하는 * nix 유틸리티입니다. PCRE는 정규식을 평가하는 방식과 다른 종류의 유한 오토마타를 포함하므로 내가 설명하는 상황에 들어 가지 않습니다. 최소 정규 표현식 구문에 대한 제안은 여전히 ​​유효하다고 생각합니다.
Rob Wells

1
POSIX 호환 시스템에서 sed는 POSIX BRE를 사용합니다. 최신 Linux 시스템의 GNU 버전은 POSIX BRE를 약간의 확장으로 사용합니다.
Jan Goyvaerts


2

문자열이 통과하는 컨텍스트 체인을 정확하게 이해하려면 시도하지 않고 언제 그리고 무엇을 피해야하는지 알아야합니다. 가장 먼 쪽에서 최종 대상까지 문자열을 지정합니다.이 대상은 정규 표현식 구문 분석 코드에서 처리하는 메모리입니다.

메모리의 문자열이 처리되는 방식에주의하십시오. 코드에서 언급 한 메모리의 변수 내부 또는 추가 평가를 통한 (문자열) 인수 또는 모든 종류의 캡슐화로 동적으로 생성 된 코드가 포함 된 문자열 ...

이 문맥 각각은 특수 기능을 가진 일부 문자를 할당했습니다.

특수 기능 (컨텍스트에 로컬)을 사용하지 않고 문자를 문자 그대로 전달하려는 경우 다음 컨텍스트의 경우 이스케이프 해야하는 경우보다 추가로 필요한 다른 이스케이프 문자가 필요할 수 있습니다. 이전 컨텍스트에서 이스케이프되었습니다. 또한 문자 인코딩과 같은 것이있을 수 있습니다 (가장 교활한 utf-8은 일반적인 문자의 ASCII처럼 보이기 때문에 선택에 따라 터미널에서도 해석 될 수 있으므로 선택적으로 다르게 해석되어 HTML의 인코딩 속성 / XML, 프로세스를 정확히 이해해야합니다.

예를 들어 perl -npe,로 시작하는 명령 행의 regexp 는 파일 핸들을 파이프로 연결 하는 일련의 exec 시스템 호출 로 전송되어야 하며,이 각각의 exec 시스템 호출은 (이스케이프되지 않은) 공백으로 구분 된 인수 목록 만 가지고 있습니다. 파이프 (|) 및 리디렉션 (> N> N> & M), 괄호, *및의 대화식 확장 ?,$(())... (모든 문자는 * sh에서 사용되는 특수 문자이며 다음 컨텍스트에서 정규 표현식의 문자를 방해하는 것처럼 보일 수 있지만 순서대로 평가됩니다. 명령 행 앞. 명령 행은 bash / sh / csh / tcsh / zsh로 프로그램하십시오. 본질적으로 큰 따옴표 또는 작은 따옴표 안에 이스케이프가 더 간단하지만 명령 행에서 문자열을 인용 할 필요는 없습니다. 왜냐하면 대부분 공백은 백 슬래시로 시작해야하고 따옴표는 * 및? 문자에 대한 확장 기능을 사용할 수있는 상태로 둘 필요는 없지만 인용 부호와 다른 컨텍스트로 구문 분석 한 다음 명령 행을 평가할 때 (명령 행에 쓰여진 것이 아닌) 메모리에서 얻은 정규 표현식이 동일한 처리를 수신합니다. 정규 표현식의 경우 대괄호 [] 안에 문자 세트 컨텍스트가 있습니다.펄 정규 표현식은 큰 비 알파 숫자 문자 (예 : m // 또는 m : / better / for / path : ...)로 인용 할 수 있습니다.

다른 답변의 문자에 대한 자세한 내용은 최종 정규 표현식 컨텍스트와 매우 관련이 있습니다. 내가 언급 한 것처럼 시도와 함께 정규 표현식 이스케이프를 찾는다는 것은 아마도 다른 컨텍스트에는 시도의 기억을 혼란스럽게하는 다른 문자 집합이 있기 때문일 수 있습니다 (백 슬래시는 해당 컨텍스트 대신 문자 대신 이스케이프 문자로 사용되는 문자입니다) ).



0

Ionic (Typescript)의 경우 문자를 스케이프하려면 슬래시를 두 번 사용해야합니다. 예를 들어 (이것은 일부 특수 문자와 일치합니다)

"^(?=.*[\\]\\[!¡\'=ªº\\-\\_ç@#$%^&*(),;\\.?\":{}|<>\+\\/])"

] [ - _ . /캐릭터에 주의하십시오 . 이중 슬래시 여야합니다. 그렇게하지 않으면 코드에 유형 오류가 발생합니다.

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