SlideShare a Scribd company logo
ES6: RegExp.prototype.unicode 이해하기
JSConf EU 2015 컨퍼런스에서 Mathias Bynens가 발표한
ES6의 RegExp.prototype.unicode 동영상을 정리하고 설명을 덧붙임
원본: https://www.youtube.com/watch?v=raJcug_vW0c
자바스크립트에서도 캐릭터의 symbol을 직접 사용할 필요 없이,
U+ 와 16진수 숫자(hexadecimal)로 코드 포인트를 직접 참조할 수 있다.
유니코드의 범위는 아래와 같이 크게 세 가지로 나눌 수 있다.
Unicode range
- U+000000 ~ U+10FFFF
BMP range (Basic Multilingual Plane)
- U+000000 ~ U+00FFFF
- 기본적인 다국어를 포함하는 범위
Astral planes range
- U+010000 ~ U+10FFFF (전체 범위의 95% 이상)
- 기본적인 다국어 외 이모지 등을 포함
자바스크립트는 Astral planes 를 두 개의 코드 포인트로 나눠 처리한다.
각각의 코드 포인트를 'surrogate half'라고 부르고, 두 코드 포인트의 조합을 'surrogate pair'라고 한다.
아래 코드를 보면 동작 방식을 이해할 수 있다.
예를 들어, !와 같이 Astral plane 레인지에 포함되어 있는 캐릭터가 있다고 가정해보자.
let poo = '!';
한 글자이지만 실제로 length를 조회해보면 2 가 리턴된다.
poo.length; //-> 2
캐릭터의 각 인덱스에 있는 코드를 확인해보자.
poo.charCodeAt(0); //-> 55357
poo.charCodeAt(0).toString(16); //-> 'd83d'
poo.charCodeAt(1); //-> 56489
poo.charCodeAt(1).toString(16); //-> 'dca9'
실제로 ! 캐릭터는 아래처럼 두 개의 유니코드로 구성되어 있다. (서로게이트 페어)
let poo2 = 'uD83DuDCA9';
물론, 두 값을 비교해도 같다.
poo === poo2; //-> true
코드 포인트를 브레이스({})로 감싸 표현하면, 자바스크립트의 기본 표현 범위(uXXXX)보다 더 큰 값의 코드 포인트를
참조할 수 있다.
let poo3 = 'u{1F4A9}';
poo2 === poo3; //-> true
위처럼 Astral plane range에 있는 캐릭터가 서로게이트 페어로 나뉘어지는 구조 때문에,
ES5에서는 Astral 캐릭터들은 정규식에서 매칭하기 어려웠다.
ES6부터는 유니코드 처리를 위한 RegExp.prototype.unicode 를 추가했고,
지금부터 설명할 u 플래그로 손쉽게 처리할 수 있게 되었다.
u flag
ES6에서는 정규식에서 유니코드를 처리할 수 있는 u 플래그가 추가됐다.
/u{61}/u.test('a'); //-> true
/u{1F4A9}/u.test('!'); //-> true
u 플래그를 생략하면 브레이스({})를 정규식의 한정 수량자로 인식한다.
/u{61}/.test('a'); //-> false, 이 정규식 구문은 'u'가 61개 있는 패턴을 의미한다.
u 플래그가 추가되면, 정규식이 스트릭트 모드(strict mode)로 동작한다고 생각하면 된다.
/abc/.test('abc'); //-> true, ES5에선 백슬래시() 뒤에 예약된 캐릭터가 오지 않는 경우 백슬래시를 무시했다.
/abc/u.test('abc'); //-> throws error
dot(.) operator
u 플래그가 붙은 경우, 닷(.) 오퍼레이터는 astral plane 에 포함된 문자열까지 포함한다.
let poo = 'a!b';
/a.b/.test(poo); //-> false
/a.b/u.test(poo); //-> true
quantifiers (수량자)
u 플래그는 astral 심볼도 한 글자로 가정해 매칭한다.
/a{2}/.test('aa'); //-> true
/!{2}/.test('!!'); //-> false
ES5에서 위 코드는 실제로 아래와 같이 서로게이트 페어로 나뉘어져 동작한다.
/uD83DuDCA9{2}/.test('uD83DuDCA9uD83DuDCA9'); //-> false
u 플래그를 사용한다면 아래처럼 의도한 결과를 볼 수 있다.
/!{2}/u.test('!!'); //-> true
Character classes
u 플래그는 캐릭터 클래스([])에 심볼이 포함된 경우도 한 글자로 처리한다.
let regex = /^[ab!]$/;
regex.test('a'); //-> true
regex.test('b'); //-> true
regex.test('!'); //-> false
마찬가지로 위 코드는 실제로 아래와 같이 서로게이트 페어로 나뉘어지기 때문이다.
let regex = /^[abuD83DuDCA9]/;
u 플래그를 적용한 경우, 의도한 대로 유니코드도 매칭된다.
let regex = /^[ab!]$/u;
regex.test('!'); //-> true
u 플래그를 사용하면 astral 캐릭터로 레인지를 표현할 수도 있다.
let regex = /[!-"]/u; // U+1F4A9 부터 U+1F4AB 까지의 심볼을 매칭한다.
regex.test('#'); //-> true (U+1F4AA)
regex.test('$'); //-> true (U+1F4AC)
u 플래그를 생략하면 range 에러가 발생하는데,
실제로 아래처럼 첫 번째 글자의 마지막 서로게이트와 두 번째 글자의 첫 서로게이트의 범위를 설정하려고 하기 때문이다.
let regex = /[!-"]/; //-> throws error
let regex = /[uD83DuDCA9-uD83DuDCAB]/;
같은 맥락에서, ES5에서는 negate 캐릭터(^)도 astral 캐릭터를 매칭하지 못했다.
/^[^a]$/.test('!'); //-> false
마찬가지로, 서로게이트 페어로 분리되어 매칭하기 때문이며,
/^[^a]$/u.test('!'); //-> true
Character class escapes
몇 가지 예약된 클래스 이스케이프가 있는데, u 플래그에서도 위에서 언급한 예제와 비슷한 맥락으로 동작한다.
d = [0-9]
D = [^0-9]
s = 공백 캐릭터
S = 공백 캐릭터가 아닌 캐릭터
w = [0-9a-zA-Z_]
W = [^0-9a-zA-Z_]
/^[^S]$/.test('!'); //-> false
u 플래그가 없다면 마찬가지로 서로게이트 페어로 분리되어 매칭하지 못한다.
/^[^S]$/u.test('!'); //-> true
With i flag
i 플래그를 u 플래그와 함께 쓰는 경우, 기본 아스키 범위 외의 유니코드 문자열과 알파벳 대소문자를 매칭할 수 있다.
let es5regex = /[a-z]/i;
let es6regex = /[a-z]/iu;
let K = 'u212A'; // 기본 알파벳이 아닌 대문자 K
es5regex.test(K); //-> false
es6regex.test(K); //-> true
하지만 W 와 함께 쓰는 경우엔 좀 헷갈리는 결과가 나온다.
let es5regex = /W/i;
let es6regex = /W/iu;
es5regex.test('S'); //-> false
es6regex.test('S'); //-> true
i 와 u 플래그가 동시에 쓰이면, W 는 더이상 w 의 반대값으로 동작하지 않는다.
HTML 문서 내에서의 패턴
HTML에서는 u 플래그가 항상 적용된 상태로 동작한다.
<style>
:invalid { background: red; }
:valid {background: green; }
</style>
<input pattern="a.b" value="aXXb"> //-> red background
<input pattern="a.b" value="a!b"> //-> green background
u 플래그 사용 가능 환경
지원 브라우저
- Microsoft Edge/Chakra (HTML 패턴 제외)
- V8 (옵션으로 --harmony-unicode-regexps 전달)
예를 들어, 커맨드라인에서 테스트해보고 싶다면 아래와 같이 실행하면 된다.
$ node --harmony_unicode_regexps
빌드 도구
- Babel 같은 빌드 도구에서 u 플래그 적용 여부에 대한 플래그가 있음
다른 라이브러리 사용
- regexpu (https://github.com/mathiasbynens/regexpu)
- XRegExp (http://xregexp.com/)

More Related Content

PDF
2 3. standard io
PDF
Javascript hoisting
PDF
2. c언어의 기본
PDF
ES6 for Node.js Study
PDF
[ES6] 9. Iterator
PDF
ES6 for Node.js Study 2주차
PDF
코딩인카페 C&JAVA 기초과정 C프로그래밍(3)
PDF
Tcpl 14장 예외처리
2 3. standard io
Javascript hoisting
2. c언어의 기본
ES6 for Node.js Study
[ES6] 9. Iterator
ES6 for Node.js Study 2주차
코딩인카페 C&JAVA 기초과정 C프로그래밍(3)
Tcpl 14장 예외처리

What's hot (7)

PDF
코딩인카페 C&JAVA 기초과정 C프로그래밍(2)
PPTX
Lua 문법
PPTX
Ruby - 6th (루비 6장 변수와 식)
PPTX
자바스크립트.
PDF
코딩인카페 C&JAVA 기초과정 C프로그래밍(1)
PPTX
You dont know_js
PPT
Equation Solving
코딩인카페 C&JAVA 기초과정 C프로그래밍(2)
Lua 문법
Ruby - 6th (루비 6장 변수와 식)
자바스크립트.
코딩인카페 C&JAVA 기초과정 C프로그래밍(1)
You dont know_js
Equation Solving
Ad

Similar to ES6: RegExp.prototype.unicode 이해하기 (14)

PDF
[octoberskyjs] Regular Expression
PDF
Unicode @KASA
PPTX
Unicode
PPTX
파이썬+정규표현식+이해하기 20160301
PPTX
Regex
PPTX
Unicode
PPTX
Unicode 이해하기
PPTX
Unicode
PDF
Unicode100
PPTX
전영규 유니코드 세미나_공개용
PPTX
Ruby 스터디
PDF
정규표현식(Regular expressions)
PDF
Unicode bidirectional algorithm
PPTX
유니코드 세미나
[octoberskyjs] Regular Expression
Unicode @KASA
Unicode
파이썬+정규표현식+이해하기 20160301
Regex
Unicode
Unicode 이해하기
Unicode
Unicode100
전영규 유니코드 세미나_공개용
Ruby 스터디
정규표현식(Regular expressions)
Unicode bidirectional algorithm
유니코드 세미나
Ad

More from Ohgyun Ahn (17)

PDF
호갱노노 이렇게 만듭니다
PDF
카카오스토리 웹팀의 코드리뷰 경험
PDF
Node.js 시작하기
PDF
JavaScript Memory Profiling
PDF
JavaScript Minification
PDF
JavaSript Template Engine
PDF
Github Usage Scenarios
PDF
diff output formats
PDF
패키지 매니저의 요건
PDF
BASH Guide Summary
PDF
Python Usage (5-minute-summary)
PDF
UX 심포지엄 20120 키노트 정리
PDF
크롬익스텐션 맛보기
PDF
재미있는 생산성 향상 도구
PDF
Raphael.js로 SVG 차트 만들기
PDF
깃헙으로 코드리뷰 하기
PDF
Recurrence relation
호갱노노 이렇게 만듭니다
카카오스토리 웹팀의 코드리뷰 경험
Node.js 시작하기
JavaScript Memory Profiling
JavaScript Minification
JavaSript Template Engine
Github Usage Scenarios
diff output formats
패키지 매니저의 요건
BASH Guide Summary
Python Usage (5-minute-summary)
UX 심포지엄 20120 키노트 정리
크롬익스텐션 맛보기
재미있는 생산성 향상 도구
Raphael.js로 SVG 차트 만들기
깃헙으로 코드리뷰 하기
Recurrence relation

ES6: RegExp.prototype.unicode 이해하기

  • 2. JSConf EU 2015 컨퍼런스에서 Mathias Bynens가 발표한 ES6의 RegExp.prototype.unicode 동영상을 정리하고 설명을 덧붙임 원본: https://www.youtube.com/watch?v=raJcug_vW0c
  • 3. 자바스크립트에서도 캐릭터의 symbol을 직접 사용할 필요 없이, U+ 와 16진수 숫자(hexadecimal)로 코드 포인트를 직접 참조할 수 있다. 유니코드의 범위는 아래와 같이 크게 세 가지로 나눌 수 있다. Unicode range - U+000000 ~ U+10FFFF BMP range (Basic Multilingual Plane) - U+000000 ~ U+00FFFF - 기본적인 다국어를 포함하는 범위 Astral planes range - U+010000 ~ U+10FFFF (전체 범위의 95% 이상) - 기본적인 다국어 외 이모지 등을 포함
  • 4. 자바스크립트는 Astral planes 를 두 개의 코드 포인트로 나눠 처리한다. 각각의 코드 포인트를 'surrogate half'라고 부르고, 두 코드 포인트의 조합을 'surrogate pair'라고 한다. 아래 코드를 보면 동작 방식을 이해할 수 있다. 예를 들어, !와 같이 Astral plane 레인지에 포함되어 있는 캐릭터가 있다고 가정해보자. let poo = '!'; 한 글자이지만 실제로 length를 조회해보면 2 가 리턴된다. poo.length; //-> 2
  • 5. 캐릭터의 각 인덱스에 있는 코드를 확인해보자. poo.charCodeAt(0); //-> 55357 poo.charCodeAt(0).toString(16); //-> 'd83d' poo.charCodeAt(1); //-> 56489 poo.charCodeAt(1).toString(16); //-> 'dca9'
  • 6. 실제로 ! 캐릭터는 아래처럼 두 개의 유니코드로 구성되어 있다. (서로게이트 페어) let poo2 = 'uD83DuDCA9'; 물론, 두 값을 비교해도 같다. poo === poo2; //-> true
  • 7. 코드 포인트를 브레이스({})로 감싸 표현하면, 자바스크립트의 기본 표현 범위(uXXXX)보다 더 큰 값의 코드 포인트를 참조할 수 있다. let poo3 = 'u{1F4A9}'; poo2 === poo3; //-> true
  • 8. 위처럼 Astral plane range에 있는 캐릭터가 서로게이트 페어로 나뉘어지는 구조 때문에, ES5에서는 Astral 캐릭터들은 정규식에서 매칭하기 어려웠다. ES6부터는 유니코드 처리를 위한 RegExp.prototype.unicode 를 추가했고, 지금부터 설명할 u 플래그로 손쉽게 처리할 수 있게 되었다.
  • 9. u flag ES6에서는 정규식에서 유니코드를 처리할 수 있는 u 플래그가 추가됐다. /u{61}/u.test('a'); //-> true /u{1F4A9}/u.test('!'); //-> true
  • 10. u 플래그를 생략하면 브레이스({})를 정규식의 한정 수량자로 인식한다. /u{61}/.test('a'); //-> false, 이 정규식 구문은 'u'가 61개 있는 패턴을 의미한다. u 플래그가 추가되면, 정규식이 스트릭트 모드(strict mode)로 동작한다고 생각하면 된다. /abc/.test('abc'); //-> true, ES5에선 백슬래시() 뒤에 예약된 캐릭터가 오지 않는 경우 백슬래시를 무시했다. /abc/u.test('abc'); //-> throws error
  • 11. dot(.) operator u 플래그가 붙은 경우, 닷(.) 오퍼레이터는 astral plane 에 포함된 문자열까지 포함한다. let poo = 'a!b'; /a.b/.test(poo); //-> false /a.b/u.test(poo); //-> true
  • 12. quantifiers (수량자) u 플래그는 astral 심볼도 한 글자로 가정해 매칭한다. /a{2}/.test('aa'); //-> true /!{2}/.test('!!'); //-> false ES5에서 위 코드는 실제로 아래와 같이 서로게이트 페어로 나뉘어져 동작한다. /uD83DuDCA9{2}/.test('uD83DuDCA9uD83DuDCA9'); //-> false u 플래그를 사용한다면 아래처럼 의도한 결과를 볼 수 있다. /!{2}/u.test('!!'); //-> true
  • 13. Character classes u 플래그는 캐릭터 클래스([])에 심볼이 포함된 경우도 한 글자로 처리한다. let regex = /^[ab!]$/; regex.test('a'); //-> true regex.test('b'); //-> true regex.test('!'); //-> false 마찬가지로 위 코드는 실제로 아래와 같이 서로게이트 페어로 나뉘어지기 때문이다. let regex = /^[abuD83DuDCA9]/; u 플래그를 적용한 경우, 의도한 대로 유니코드도 매칭된다. let regex = /^[ab!]$/u; regex.test('!'); //-> true
  • 14. u 플래그를 사용하면 astral 캐릭터로 레인지를 표현할 수도 있다. let regex = /[!-"]/u; // U+1F4A9 부터 U+1F4AB 까지의 심볼을 매칭한다. regex.test('#'); //-> true (U+1F4AA) regex.test('$'); //-> true (U+1F4AC) u 플래그를 생략하면 range 에러가 발생하는데, 실제로 아래처럼 첫 번째 글자의 마지막 서로게이트와 두 번째 글자의 첫 서로게이트의 범위를 설정하려고 하기 때문이다. let regex = /[!-"]/; //-> throws error let regex = /[uD83DuDCA9-uD83DuDCAB]/;
  • 15. 같은 맥락에서, ES5에서는 negate 캐릭터(^)도 astral 캐릭터를 매칭하지 못했다. /^[^a]$/.test('!'); //-> false 마찬가지로, 서로게이트 페어로 분리되어 매칭하기 때문이며, /^[^a]$/u.test('!'); //-> true
  • 16. Character class escapes 몇 가지 예약된 클래스 이스케이프가 있는데, u 플래그에서도 위에서 언급한 예제와 비슷한 맥락으로 동작한다. d = [0-9] D = [^0-9] s = 공백 캐릭터 S = 공백 캐릭터가 아닌 캐릭터 w = [0-9a-zA-Z_] W = [^0-9a-zA-Z_] /^[^S]$/.test('!'); //-> false u 플래그가 없다면 마찬가지로 서로게이트 페어로 분리되어 매칭하지 못한다. /^[^S]$/u.test('!'); //-> true
  • 17. With i flag i 플래그를 u 플래그와 함께 쓰는 경우, 기본 아스키 범위 외의 유니코드 문자열과 알파벳 대소문자를 매칭할 수 있다. let es5regex = /[a-z]/i; let es6regex = /[a-z]/iu; let K = 'u212A'; // 기본 알파벳이 아닌 대문자 K es5regex.test(K); //-> false es6regex.test(K); //-> true
  • 18. 하지만 W 와 함께 쓰는 경우엔 좀 헷갈리는 결과가 나온다. let es5regex = /W/i; let es6regex = /W/iu; es5regex.test('S'); //-> false es6regex.test('S'); //-> true i 와 u 플래그가 동시에 쓰이면, W 는 더이상 w 의 반대값으로 동작하지 않는다.
  • 19. HTML 문서 내에서의 패턴 HTML에서는 u 플래그가 항상 적용된 상태로 동작한다. <style> :invalid { background: red; } :valid {background: green; } </style> <input pattern="a.b" value="aXXb"> //-> red background <input pattern="a.b" value="a!b"> //-> green background
  • 20. u 플래그 사용 가능 환경 지원 브라우저 - Microsoft Edge/Chakra (HTML 패턴 제외) - V8 (옵션으로 --harmony-unicode-regexps 전달) 예를 들어, 커맨드라인에서 테스트해보고 싶다면 아래와 같이 실행하면 된다. $ node --harmony_unicode_regexps 빌드 도구 - Babel 같은 빌드 도구에서 u 플래그 적용 여부에 대한 플래그가 있음 다른 라이브러리 사용 - regexpu (https://github.com/mathiasbynens/regexpu) - XRegExp (http://xregexp.com/)