대괄호 […]
안의 여러 문자나 문자 클래스는 "주어진 문자 중 아무 문자나 검색"을 의미합니다.
예를 들어, pattern:[eao]
는 'a'
, 'e'
또는 'o'
3가지 문자 중 하나를 의미합니다.
이것을 세트라고 합니다. 세트는 일반 문자와 함께 정규식에 사용할 수 있습니다.
// [t 또는 m], 그리고 "op"를 찾습니다.
alert( "Mop top".match(/[tm]op/gi) ); // "Mop", "top"
세트에는 여러 문자가 있지만, 매치 항목에서 정확히 하나의 문자에 해당한다는 점을 유의해야 합니다.
따라서 아래 예시는 어떤 것과도 일치하지 않습니다.
// "V", [o 또는 i], 그리고 "la"를 찾습니다.
alert( "Voila".match(/V[oi]la/) ); // null, 일치하지 않습니다.
해당 패턴은 다음 항목을 검색합니다.
pattern:V
,- 그런 다음 문자
pattern:[oi]
중 하나, - 그리고
pattern:la
.
따라서 match:Vola
또는 match:Vila
와 일치할 것입니다.
대괄호에는 문자 범위가 포함될 수도 있습니다.
예를 들어, pattern:[a-z]
는 a
부터 z
까지의 문자이고, pattern:[0-5]
는 0
부터 5
까지의 숫자입니다.
아래 예시에서는 "x"
다음에 A
부터 F
까지의 두 자리 숫자 또는 문자를 검색합니다.
alert( "Exception 0xAF".match(/x[0-9A-F][0-9A-F]/g) ); // xAF
여기 pattern:[0-9A-F]
에는 두 가지 범위가 있습니다. 0
부터 9
까지의 숫자나 A
부터 F
까지의 문자에 포함되는 문자 하나를 검색합니다.
소문자도 찾고 싶다면 a-f
: pattern:[0-9A-Fa-f]
범위를 추가할 수 있습니다. 또는 플래그 pattern:i
를 사용할 수 있습니다.
또한 […]
내에서 문자 클래스를 사용할 수도 있습니다.
예를 들어, 단어로 된 문자 pattern:\w
또는 하이픈 pattern:-
을 찾고자 한다면 세트는 pattern:[\w-]
입니다.
여러 클래스를 결합하는 것도 가능합니다. pattern:[\s\d]
는 "공백 문자 또는 숫자"를 의미합니다.
예시:
- **\d** -- `pattern:[0-9]`와 같습니다,
- **\w** -- `pattern:[a-zA-Z0-9_]`와 같습니다,
- **\s** -- `pattern:[\t\n\v\f\r ]`와 같으며, 다른 희귀한 유니코드 공백 문자가 거의 없습니다.
문자 클래스 pattern:\w
는 pattern:[a-zA-Z0-9_]
의 약어이므로 중국어 상형 문자, 키릴 문자 등을 찾을 수 없습니다.
우리는 어떤 언어에서든, 단어로 된 문자를 찾기 위해 더욱 보편적인 패턴을 작성할 수 있습니다. 이는 유니코드 속성을 사용하면 쉽습니다. pattern:[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]
해독해 봅시다. pattern:\w
와 유사하게, 다음과 같은 유니코드 속성을 가진 문자를 포함하는 고유한 세트를 만들고 있습니다.
Alphabetic
(Alpha
) - 문자,Mark
(M
) - 악센트,Decimal_Number
(Nd
) - 숫자,Connector_Punctuation
(Pc
) - 밑줄'_'
및 유사한 문자,Join_Control
(Join_C
) - 예를 들어, 아랍어와 같은 기호에서 사용되는 두 특수 코드200c
및200d
.
사용 예:
let regexp = /[\p{Alpha}\p{M}\p{Nd}\p{Pc}\p{Join_C}]/gu;
let str = `Hi 你好 12`;
// 모든 문자와 숫자를 찾습니다.
alert( str.match(regexp) ); // H,i,你,好,1,2
물론 이 패턴은 유니코드 속성을 추가하거나 제거하여 편집할 수 있습니다. 유니코드 속성은 info:regexp-unicode 문서에 자세히 설명되어 있습니다.
유니코드 속성 `pattern:p{…}`는 아직 Edge와 Firefox에 구현되지 않았습니다. 정말 필요하다면, [XRegExp](http://xregexp.com/) 라이브러리를 사용할 수 있습니다.
혹은 관심 있는 언어의 문자 범위를 사용하세요. 키릴 문자의 경우 `pattern:[а-я]`.
일반적인 범위 외에도, pattern:[^…]
처럼 보이는 "제외" 범위가 있습니다.
시작 부분에 캐럿 문자 ^
로 표시되며 주어진 문자를 제외한 모든 문자와 일치합니다.
예시:
pattern:[^aeyo]
--'a'
,'e'
,'y'
또는'o'
를 제외한 모든 문자.pattern:[^0-9]
-- 숫자를 제외한 모든 문자,pattern:\D
와 동일.pattern:[^\s]
-- 공백이 아닌 모든 문자,\S
와 동일.
아래 예시는 문자, 숫자, 공백을 제외한 모든 문자를 찾습니다.
alert( "[email protected]".match(/[^\d\sA-Z]/gi) ); // @ 그리고 .
일반적으로 특수 문자를 정확히 찾으려면 pattern:\.
과 같이 이스케이프해야 합니다. 그리고 역슬래시가 필요한 경우 pattern:\\
등을 사용합니다.
대괄호 안에는 대부분의 특수 문자를 이스케이프하지 않고 사용할 수 있습니다.
- 기호
pattern:. + ( )
는 이스케이프가 필요하지 않습니다. - 하이픈
pattern:-
은 시작이나 끝에서 이스케이프되지 않습니다(범위를 정의하지 않는 경우). - 캐럿
pattern:^
은 시작 부분에서만 이스케이프됩니다(제외를 의미). - 닫는 대괄호
pattern:]
는 항상 이스케이프됩니다(해당 기호를 찾아야 하는 경우).
즉, 대괄호를 의미하는 경우를 제외하고 모든 특수 문자는 이스케이프 없이 허용됩니다.
대괄호 안에 점 .
은 단순히 점을 의미합니다. 패턴 pattern:[.,]
은 점이나 쉼표 문자 중 하나를 찾습니다.
아래 예에서 정규식 pattern:[-().^+]
은 -().^+
문자 중 하나를 찾습니다.
// 이스케이프가 필요하지 않습니다.
let regexp = /[-().^+]/g;
alert( "1 + 2 - 3".match(regexp) ); // +, -와 일치합니다.
그러나 "만약을 대비하여" 이스케이프하기로 결정했어도 아무런 문제가 없을 것입니다.
// 모든 것을 이스케이프
let regexp = /[\-\(\)\.\^\+]/g;
alert( "1 + 2 - 3".match(regexp) ); // +, -로 작동합니다.
세트에 서로게이트 쌍이 있는 경우, 올바르게 작동하려면 플래그 pattern:u
가 필요합니다.
예를 들어, subject:𝒳
문자열에서 pattern:[𝒳𝒴]
를 찾아보겠습니다.
alert( '𝒳'.match(/[𝒳𝒴]/) ); // [?]와 같은 이상한 문자를 보여줍니다.
// (검색이 잘못 수행되어 반 문자 반환)
기본적으로 서로게이트 쌍에 대해 "모르는" 정규 표현식이 있기 때문에 결과가 올바르지 않습니다.
정규 표현식 엔진은 [𝒳𝒴]
가 두 글자가 아니라, 네 글자라고 생각합니다.
𝒳
의 왼쪽 절반(1)
,𝒳
의 오른쪽 절반(2)
,𝒴
의 왼쪽 절반(3)
,𝒴
의 오른쪽 절반(4)
.
다음과 같은 코드를 볼 수 있습니다.
for(let i=0; i<'𝒳𝒴'.length; i++) {
alert('𝒳𝒴'.charCodeAt(i)); // 55349, 56499, 55349, 56500
};
따라서, 위의 예는 𝒳
의 왼쪽 절반을 찾아서 보여줍니다.
플래그 pattern:u
를 추가한다면 올바르게 동작할 것입니다.
alert( '𝒳'.match(/[𝒳𝒴]/u) ); // 𝒳
[𝒳-𝒴]
와 같이 범위를 찾을 때도 비슷한 상황이 발생합니다.
플래그 pattern:u
를 추가하는 것을 잊었다면, 에러가 발생할 것입니다.
'𝒳'.match(/[𝒳-𝒴]/); // Error: Invalid regular expression
그 이유는, 플래그 pattern:u
가 없는 서로게이트 쌍은 두 문자로 인식되기 때문에 [𝒳-𝒴]
가 [<55349><56499>-<55349><56500>]
로 해석됩니다(모든 서로게이트 쌍은 해당 코드로 대체). 이제 56499-55349
범위가 유효하지 않음을 쉽게 알 수 있습니다. 시작 코드 56499
는 끝 코드 55349
보다 큽니다. 이것이 에러의 공식적인 이유입니다.
플래그 pattern:u
를 사용하면 패턴이 올바르게 작동합니다.
// 𝒳부터 𝒵까지의 문자를 찾습니다.
alert( '𝒴'.match(/[𝒳-𝒵]/u) ); // 𝒴