Skip to content

Latest commit

 

History

History
197 lines (126 loc) · 8.15 KB

File metadata and controls

197 lines (126 loc) · 8.15 KB

세트와 범위 [...]

대괄호 […] 안의 여러 문자나 문자 클래스는 "주어진 문자 중 아무 문자나 검색"을 의미합니다.

세트

예를 들어, 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 ]`와 같으며, 다른 희귀한 유니코드 공백 문자가 거의 없습니다.

예시: 다국어 \w

문자 클래스 pattern:\wpattern:[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) - 예를 들어, 아랍어와 같은 기호에서 사용되는 두 특수 코드 200c200d.

사용 예:

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) ); // +, -로 작동합니다.

범위와 플래그 "u"

세트에 서로게이트 쌍이 있는 경우, 올바르게 작동하려면 플래그 pattern:u가 필요합니다.

예를 들어, subject:𝒳 문자열에서 pattern:[𝒳𝒴]를 찾아보겠습니다.

alert( '𝒳'.match(/[𝒳𝒴]/) ); // [?]와 같은 이상한 문자를 보여줍니다.
// (검색이 잘못 수행되어 반 문자 반환)

기본적으로 서로게이트 쌍에 대해 "모르는" 정규 표현식이 있기 때문에 결과가 올바르지 않습니다.

정규 표현식 엔진은 [𝒳𝒴]가 두 글자가 아니라, 네 글자라고 생각합니다.

  1. 𝒳의 왼쪽 절반 (1),
  2. 𝒳의 오른쪽 절반 (2),
  3. 𝒴의 왼쪽 절반 (3),
  4. 𝒴의 오른쪽 절반 (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) ); // 𝒴