Search

반응형

'정규표현식'에 해당되는 글 4건

  1. 2023.01.08 [자바스크립트]정규표현식 Quantifiers, 수량자 정규식
  2. 2022.12.24 [자바스크립트]정규표현식 어썰션, Assertions
반응형

안녕하세요. 신기한 연구소입니다.

이번 포스팅은 역시 자바스크립트 정규표현식 중 수량자(quantifiers)에 대해 같이 코딩하면서 

기능을 살펴보겠습니다.

 

자주 사용하지는 않지만 알아두면 좋은 자바스크립트 정규 표현식 중 수량자(Quantifiers)는

패턴 문자의 반복에 관해 관여하고 매칭시킵니다.

 

Quantifiers(수량자) 란?

매칭할 문자 또는 표현식의 수를 나타냅니다.

 

문자*

* 앞에 문자가 0개 또는 그 이상 있으면 매칭됩니다.

0개라는 의미는 매칭되는 문자가 없어도 매칭이 됩니다.

예를 통해 살펴봅니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var reg1 = /go*/;
var text1 = 'good morning';
console.log(text1.match(reg1));
//[ 'goo', index: 0, input: 'good morning', groups: undefined ]
 
text1 = 'oh my ghoat';
console.log(text1.match(reg1));
//[ 'g', index: 6, input: 'oh my ghoat', groups: undefined ]
 
text1 = 'my favorite things';
console.log(text1.match(reg1));
//[ 'g', index: 16, input: 'my favorite things', groups: undefined ]
 
text1 = 'hello my friend';
console.log(text1.match(reg1));
//null
cs

패턴은 /go*/로 영문자 g로 시작하고 o가 없거나 1개 이상 매칭되면 됩니다.

4번 라인 결과를 보면 good의 go*패턴으로 o가 2번 나와서 goo가 출력됨을 확인합니다.

7번 라인 결과를 보면 ghoat의 go*패턴으로 g는 있고 o는 0번 매칭되기에 g가 출력됨을 확인합니다. 

11번 라인 결과를 보면 things의 go*패턴으로 g는 있고 o는 0번 매칭되기에 g가 출력됨을 확인합니다.

16번 라인 결과를 보면 문장에 g가 아예 없기에 매칭되는 부분이 없어 null이 출력됨을 확인합니다.

 

문자+

+는 무조건 문자가 1개 이상 매칭되어야 합니다.

뒤에서 배우는 {1, }와 같은 의미입니다.

예제를 같이 코딩하면서 살펴봅니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var reg2 = /go+/;
var text2 = 'goooooood morning';
console.log(text2.match(reg2));
//[ 'gooooooo', index: 0, input: 'goooooood morning', groups: undefined ]
 
text2 = 'oh my ghooooat';
console.log(text2.match(reg2));
//null
 
text2 =  'my favorite things';
console.log(text2.match(reg2));
//null
 
text2 = 'hello my friend';
console.log(text2.match(reg2));
//null
cs

 

4번라인 결과를 보면 goooooood의 go+패턴으로 gooooooo가 출력됨을 확인합니다.

8번 라인 결과는 gh가 보이지만 최소한 o가 1개 이상이어야 하기에 매칭이 없어 null이 출력됩니다.

12번 라인 결과도 things에서 g는 있지만 o가 없기에 null이 출력됩니다.

16번 라인 결과는 g가 아예 없기에 hello의 o와도 매칭이 안되기에 null을 출력합니다.

 

문자?

?는 앞 문자가 0번 또는 1번만 매칭되는 경우를 의미합니다.

역시 예제를 같이 코딩하면서 알아봅니다.

 

1
2
3
4
5
6
7
8
var reg3 = /e?de?/;
var text3 = 'helped';
console.log(text3.match(reg3));
//[ 'ed', index: 4, input: 'helped', groups: undefined ]
 
text3 = 'coffee grande';
console.log(text3.match(reg3));
//[ 'de', index: 11, input: 'coffee grande', groups: undefined ]
cs

 

4번 라인 결과를 보면 helped에서 패턴 /e?de?/ 중 e?d와 ed가 매칭되어 결과를 보여줍니다.

8번 라인 결과를 보면 grande에서 패턴 /e?de?/ 중 de?와 de가 매칭되어 결과를 보여줍니다.

e가 없어도 되기에 d만 있다면 매칭됩니다.

 

문자{n}

양의 정수 n만큼 정확히 문자수가 일치해야 합니다.

역시 예제 코딩을 통해 같이 알아봅니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
var reg4 = /o{3}/;
var text4 = 'google';
console.log(text4.match(reg4));
//null
 
text4 = 'gooogle';
console.log(text4.match(reg4));
//[ 'ooo', index: 1, input: 'gooogle', groups: undefined ]
 
text4 = 'goooooogle';
console.log(text4.match(reg4));
//[ 'ooo', index: 1, input: 'goooooogle', groups: undefined ]]
cs

 

4번라인 결과는 google에서 패턴 /o{3}/인 o가 정확히 3개 있는 패턴과 매칭되지 않아서 null이 됩니다.

8번라인 결과는 gooogle에서 패턴 o가 정확히 3개 있기에 매칭되어 ooo가 출력됩니다.

12번라인 결과도 goooooogle에서 패턴o가 정확히 3개 있기에 ooo가 출력되고 뒤의 나머지 o는 무시됩니다.

 

문자{n, }

양의 정수 n만큼 문자가 최소한 일치해야 합니다.

/a{2,}/는 a가 최소 2개 이상은 있어야 한다는 의미입니다.

예제 코딩으로 결과를 알아봅니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
var reg5 = /o{1,}/;
var text5 = 'zoo park';
console.log(text5.match(reg5));
//[ 'oo', index: 1, input: 'zoo park', groups: undefined ]
 
text5 = 'zo';
console.log(text5.match(reg5));
//[ 'o', index: 1, input: 'zo', groups: undefined ]
 
reg5 = /o{3,}/;
text5 = 'zooooo';
console.log(text5.match(reg5));
//[ 'ooooo', index: 1, input: 'zooooo', groups: undefined ]
cs

 

4번 라인 결과는 zoo에서 패턴/o{1,}/ 최소 o가 한 개 이상이어야 하기에 oo가 출력됩니다.

8번 라인 결과는 zo에서 최소 o가 한 개이기에 o가 출력됩니다.

13번 라인 결과는 zooooo에서 패턴이 최소 o가 3개 이상이어야 해서 ooooo이 출력되었습니다.

 

문자{n,m}

문자가 최소 n개 이상부터 m개까지 매칭됩니다.

m은 항상 n보다 커야 합니다. (n < m)

매칭되는 문자수가 m보다 많아도 m만큼만 일치해서 출력합니다.

예제 코딩으로 같이 살펴봅니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var reg6 = /o{1,3}/;
var text6 = 'zo';
console.log(text6.match(reg6));
//[ 'o', index: 1, input: 'zo', groups: undefined ]
 
text6 = 'zoo';
console.log(text6.match(reg6));
//[ 'oo', index: 1, input: 'zoo', groups: undefined ]
 
text6 = 'zooo';
console.log(text6.match(reg6));
//[ 'ooo', index: 1, input: 'zooo', groups: undefined ]
 
text6 = 'zoooooo';
console.log(text6.match(reg6));
//[ 'ooo', index: 1, input: 'zoooooo', groups: undefined ]
cs

 

4번 라인 결과를 보면 zo에서 /o{1,3}/인 o가 최소 1개부터 3개까지의 패턴에 o가 1개 있어 매칭됩니다.

8번 라인 결과를 보면 zoo에서는 oo가 2개이기에 패턴에 매칭됩니다.

12번 라인 결과를 보면 zooo에서 ooo 가 최대 3개로 매칭됩니다.

16번 라인 결과를 보면 zoooooo에서 o가 최대 3개까지로 ooo만 매칭됩니다.

 

지금까지 자바스크립트 정규 표현식 중 수량자(Quantifiers)에 대해 이해하고

같이 코딩해 봤습니다.

 

반응형
반응형

안녕하세요. 신기한 연구소입니다.

자바스크립트 정규표현식(Javascript Regular expressions)을 공부 중인데요.

정말 쉽게 이해하기 힘든 부분이네요.

왜 이렇게 어려운 걸까요?

사실 실전에서 자주 코딩에 사용하지 않는 부분인데...

그래도 언제 어디서 만날지 모르기에 준비하는 마음으로 같이 공부해 보기로 해요.

이번 포스팅은 자바스크립트 정규표현식 중 Assertions에 대해 같이 알아보겠습니다.

 

 Assertions 의미.

표명. 의사나 태도를 분명하게 드러냄.

논리적으로 맞다는 가정을 해서 만약 가정과 안 맞으면 프로그램을 종료하는

그런 목적으로 에러 검출용으로도 사용한다는 내용도 있습니다.

그래도 무슨 의미인지 사실 와닿지 않습니다.

그렇다면 바로 예제를 통해 하나씩 살펴보면

어떤 의미이고 어떻게 사용하는 건지 쉽게 이해할 수 있답니다.

 

Assertions 종류

{ ^, $, \b, \B }

x(?=y), x(?!y), (?<=y)x, (?<!y)x

특수문자나 수학 공식처럼 생겼네요.

그럼 하나씩 어떤 의미를 가지고 있는지 같이 코딩하면서 알아보겠습니다.

 

^ 문자.

키보드 숫자 6에 보면 ^가 있습니다.

의미는 패턴을 적용할 문장의 가장 앞부분만 확인합니다.

 

1
2
3
4
5
6
7
8
9
10
11
//1st
let text1 = 'My name is Mike.';
let reg1 = /^M/;
console.log(text1.match(reg1));
//['M', index: 0, input: 'My name is Mike.', groups: undefined]
 
//2nd
text1 = 'His name is Mike.';
reg1 = /^M/;
console.log(text1.match(reg1));
//null
cs

예제 2개를 코딩했는데요.

1st는 패턴 reg1이 /^M/으로 문장 text1에서 가장 앞부분이 대문자 M으로 시작하는지 찾는 패턴입니다.

let text1 = 'My name is Mike.';

text1의 가장 앞은 My로 시작합니다.

그래서 /^M/ 패턴과 매칭이 되기에 위 예제 5번 줄처럼 결과가 나옵니다.

2nd 예제는 같은 패턴에 문장이 바뀌었습니다.

가장 앞부분이 대문자 M인지 체크하지만 문장의 마지막 단어에서 Mike를 찾을 수 있습니다.

'His name is Mike';

가장 앞부분은 H로 시작하기에 /^M/ 과 매칭되지 않기에 null을 리턴합니다.

Mike를 찾고 싶다면 /^M/에서 ^만 빼면 됩니다. /M/

 

$ 문자.

키보드 숫자 4에 보면 $가 있습니다.

미국 달러 표시입니다.

^와는 대응되는 개념으로 맨 뒤의 단어를 확인합니다.

 

1
2
3
4
let text2 = 'My name is Smith';
let reg2 = /h$/;
console.log(reg2.exec(text2));
//['h', index: 15, input: 'My name is Smith', groups: undefined]
cs

패턴 reg2는 /h$/입니다.

이 패턴을 해석하면 h라는 문자는 문장의 끝($)에 있어야 한다는 의미입니다.

그래서 /$h/로 하면 패턴 생성 오류이고 반드시 위 빨간색 문장을 읽는 순서대로 /h$)/로

패턴을 만들어야 합니다.

text2 = 'My name is Smith';

마지막이 h이며 그 뒤로 없기에 $ 패턴과 일치합니다.

그래서 결과는 h가 나오게 됩니다.

 

1
2
3
4
5
6
text2 = `My name is Smith
Wool`;
 
reg2 = /h$/;
console.log(reg2.exec(text2));
//null
cs

위 예제는 문명 text2의 끝이 h인데 왜 null이 나올까요?

바로 줄 바꿈 때문인데요.

틱(`, 키보드 좌측 상단이 있음)으로 문장을 감싸고 줄 바꿈을 했습니다.

자바스크립트에서 틱을 사용하면 줄바꿈 한 그대로 인식됩니다.

Smith 후 줄 바꿈이 되고 Wool로 문장이 끝납니다.

그렇기에 /h$/가 아닌 l이 문장의 마지막이다라는 /l$/로 해야 

"l"이 정상적으로 검색이 됩니다.

 

1
2
3
4
5
6
7
8
9
10
11
12
text2 = `My name is Smith
Wool`;
 
reg2 = /h$/m;
console.log(reg2.exec(text2));
//'h', index: 15, input: 'My name is Smith
//Wool', groups: undefined]
 
reg2 = /l$/m;
console.log(reg2.exec(text2));
//['l', index: 20, input: 'My name is Smith
//Wool', groups: undefined]
cs

패턴에 m 플래그를 사용했습니다.

reg2 = /h$/m;

그 결과 줄 바꿈 한 경우 각 줄마다 마지막 글자를 체크할 수 있게 되었습니다.

h와 l 두 글자 모두 각 줄마다 체크가 되어 검색이 되었습니다.

 

\b 문자.

역슬래시와 소문자 b를 결합하는 패턴입니다.

기능은 boundary(범위)를 가지고 패턴을 정하는 것입니다.

무슨 의미인지 예를 통해 알아보겠습니다.

1
2
3
4
5
6
7
8
9
10
let text3 = "They are students";
let reg3 = /\bs/;
 
console.log(text3.match(reg3));
//['s', index: 9, input: 'They are students', groups: undefined]
 
reg3 = /s\b/;
 
console.log(text3.match(reg3));
//['s', index: 16, input: 'They are students', groups: undefined]
cs

let reg3 = /\bs/;

\b 는 범위 앞쪽을 의미하며 s로  시작하는 단어를 찾습니다.

They, are, sutduets 이 세 개의 단어로 구성된 문장은

공백을 기준으로 범위가 지정됩니다.

첫 번째 범위는 They, 두 번째 범위는 are, 세 번째 범위는 students이며

공백을 기준으로 단어의 바로 앞에서 끝을 \b로 확인할 수 있습니다.

@They@ @are@ @students@

@를 \b의 위치로 이해하면 쉽지요?

아래 예를 같이 코딩하면서 살펴보겠습니다. (자바스크립트 정규표현식)

1
2
3
4
5
6
7
8
9
10
11
reg3 = /\b\w+\b/;
console.log(text3.match(reg3));
//['They', index: 0, input: 'They are students', groups: undefined]
 
reg3 = /\ba\w+\b/;
console.log(text3.match(reg3));
//['are', index: 5, input: 'They are students', groups: undefined]
 
reg3 = /\b\w+e\b/;
console.log(text3.match(reg3));
//['are', index: 5, input: 'They are students', groups: undefined]
cs

1번 라인은 범위(\b)를 기준으로 모든 문자(\w+) 그리고 범위(\b)를 의미하며

공백으로 구분되는 처음 만나는 단어를 의미합니다.

그래서 They가 검색되었습니다.

5번 라인은 범위 내(\b      \b)에서 a로 시작하는 단어(a\w+)를 찾는 패턴입니다.

a로 시작하는 are가 검색되겠네요.

9번 라인은 범위 내(\b     \b)에서 단어가 e로 끝나는 (\w+e) 를 찾는 패턴입니다.

e로 끝나는 are가 검색되겠네요.

 

\B 문자.

역슬래시와 대문자 B를 결합하는 패턴입니다.

자바스크립트 정규표현식에서는 대문자는 소문자의 반대 개념으로 이해하면 됩니다.

\B는 공백으로 구분되는 시작과 끝이 아닌 그 내부의 위치가 범위로 잡힙니다.

@They@ @are@ @students@   \b

T@h@e@y a@r@e s@t@u@d@e@n@t@s   \B

위 예문처럼 \b는 단어의 시작 전과 끝의 바로 뒤를 범위로 잡지만

\B는 단어 내 철자 사이를 범위로 정하게 됩니다.

예제를 통해 같이 코딩하며 확인해 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
let text4 = "abcd efg";
let reg4 = /c\B/;
 
console.log(text4.match(reg4));
//['c', index: 2, input: 'abcd efg', groups: undefined]
 
reg4 = /\Bc\B/;
console.log(text4.match(reg4));
//['c', index: 2, input: 'abcd efg', groups: undefined]
 
reg4 = /a\B/;
console.log(text4.match(reg4));
//['a', index: 0, input: 'abcd efg', groups: undefined]
 
reg4 = /\Ba\B/;
console.log(text4.match(reg4));
//null
 
reg4 = /d\B/;
console.log(text4.match(reg4));
//null
 
reg4 = /\Ba/;
console.log(text4.match(reg4));
//null
cs

2번 라인의 패턴은 c문자 뒤에 \B 범위가 있어야 합니다.

text4를 보면 첫 단어 abcd에 c가 있고 패턴에서 그 앞에 어떤 것도 없기에

c만 있으면 됩니다. 하지만 c\B로 패턴을 만들었기에 c 다음에는 공백이나

c가 마지막 철자면 안됩니다. 다행히도 c다음에 d가 있고 c와 d 사이는

\B 문자가 인식되므로 c는 패턴에 적합해서 검색됩니다.

c 앞에 b도 있기에 패턴을 \Bc\B로 해도 c가 검색됩니다.

abcd는 \B를 적용한다면 a@b@c@d처럼 생각하면 c 앞 뒤로 @가 있기에

\B와 매칭됩니다. (실제 @는 없는 그냥 \B의 범위를 설명하고자 사용한 기호일 뿐입니다.)

11번 라인의 패턴은 /a\B/로 a 앞은 뭐든 관계없고 a글자 뒤에 다른 철자가 있어야 하는

패턴으로 생각하면 됩니다. a 다음에는 b가 있고 ab 사이에는 \B 에 일치됩니다.

그래서 a가 검색됩니다.

15번 라인의 패턴은 /\Ba\B/인데 a 철자 앞 뒤로 공백제외, 시작도 끝도 아니어야 하지만

abcd에서 a 앞에는 아무것도 없는 시작부입니다. 그래서 패턴에 매칭되지 않고 null이 됩니다.

19번과 23번도 공백제외, 시작도 끝도 아니어야 하는 부분에 매칭되지 않아서 null이 됩니다.

 

x(?=y) 패턴.

x뒤에 y가 오면 매칭되는 패턴입니다. 공백도 포함되니 설정할 때 주의해야 합니다.

예제를 같이 코딩하면서 확인해 보겠습니다. 백문불여일견~

1
2
3
4
5
6
7
8
9
10
11
let text5 = "abcd efg hijk";
let reg5 = /abcd(?= efg)/;
 
console.log(text5.match(reg5));
//['abcd', index: 0, input: 'abcd efg hijk', groups: undefined]
 
text5 = "abcd hijk";
reg5 = /abcd(?= efg| hijk)/;
 
console.log(text5.match(reg5));
//['abcd', index: 0, input: 'abcd hijk', groups: undefined]
cs

/abcd(?= efg)/ 패턴은 'abcd' 다음에 ' efg'가 오는 패턴을 찾는다는 의미입니다.

' efg'의 e 앞에 공백이 있음을 주의하세요. 공백이 없으면 위 결과는 null이 됩니다.

8번 라인의 패턴은 '|'를 사용했습니다. or 의미인데요.

' efg| hijk'는 둘 중 하나와 매칭되면 검색이 됩니다.

위 예제에서는 'abcd' 다음에 ' hijk'가 매칭돼서 검색이 되는 패턴입니다.

 

x(?!y) 패턴.

!는 부정의 의미입니다. x뒤에 y가 아니면 매칭되는 패턴입니다. 

역시 예제로 같이 코딩하면서 알아보는 게 좋겠네요.

1
2
3
4
5
6
7
8
9
10
11
let text6 = "apple,pear";
let reg6 = /\w+(?!\,)/g;
 
console.log(text6.match(reg6));
//['appl', 'pear']
 
text6 = '0.999';
reg6 = /\d+(?!\.)/g;
 
console.log(text6.match(reg6));
['999']
cs

2번 라인의 패턴을 읽어보겠습니다.

/패턴의 시작이고 \w+는 문자열이며 (?!\,) 는 콤마(,)와 일치하지 않는다이며

/g는 global 플래그로 구문 전체를 찾는다는 의미입니다.

콤마는 특수문자로 앞에 역슬래시\를 붙여줘야 콤마로 인식됩니다.

apple,pear에서 콤마(,)를 달고 있는 철자는 apple의 e입니다.

그래서 콤마를 달고 있는 e,는 제외하고 결과가 검색되었습니다.

숫자 테스트 8번 라인처럼 패턴을 정하도록 합니다.

숫자로 된 구문에서 점(.)을 달고 있는 숫자는 빼고 검색하라는 패턴입니다.

점(.)은 0이 달고 있기에 0.을 제외한 999가 검색되었습니다.

 

(?<=y)x 패턴.

x는 앞의 y가 오면 매칭되는 패턴입니다. 공백도 포함되니 설정할 때 주의해야 합니다.

또한 <기호도 빠트리면 안 됩니다.

예제를 같이 코딩하면서 확인해 보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
let text7 = "abcd efg hijk";
let reg7 = /(?<=abcd )efg/;
 
console.log(text7.match(reg7));
//['efg', index: 5, input: 'abcd efg hijk', groups: undefined]
 
text7 = "abcd efg hijk";
reg7 = /(?<=abcd |efg )hijk/;
 
console.log(text7.match(reg7));
//['hijk', index: 9, input: 'abcd efg hijk', groups: undefined]
cs

2번 라인의 패턴을 분석해 봅니다.

(?<=abcd ) 는 'abcd '가 'efg' 앞에 있어야 하는 패턴이라고 해석합니다.

'efg' 앞에 'abcd '가 있기 때문에 'efg'가 검색되었습니다.

8번 라인 패턴은 '|' 인 or를 사용했고 둘 중 하나가 앞에 있으면 검색됩니다.

역시 'efg '가 있기에 'hijk'가 매칭되어 검색이 되었습니다.

 

(?<!y)x 패턴.

!는 부정의 의미입니다.

y를 앞에 달고 있는 문자가 있으면 제외하고 다음 x문자가 온다는 의미입니다.

예제를 코딩하며 알아보겠습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
let text8 = "apple,pear";
let reg8 = /(?<!,)\w+/;
 
console.log(text8.match(reg8));
//['apple', index: 0, input: 'apple,pear', groups: undefined]
 
text8 = ",pear";
reg8 = /(?<!,)\w+/;
 
console.log(text8.match(reg8));
//['ear', index: 2, input: ',pear', groups: undefined]
 
text8 = "3.215";
reg8 = /(?<!.)\d+/;
 
console.log(text8.match(reg8));
//['3', index: 0, input: '3.215', groups: undefined]
cs

2번 라인 패턴은 ,를 앞에 붙인 단어는 제외한다는 의미입니다.

,p를 제외하면 바로 앞 apple이 검색됩니다.

전역 /g 플래그가 없으니 apple만 검색됩니다.

8번 라인은 콤마(,)를 앞에 붙인 글자를 제외합니다.

여기서 콤마에 역슬래시를 안 해도 인식이 됩니다.

',pear'에서 콤마가 붙은 p를 제외하면 'ear'이 검색됩니다.

14번 라인은 숫자로 패턴을 만들어봤습니다.

점(.)을 달고 있는 숫자는 제외하고 검색하게 합니다.

'3.215' 에서 점을 달고 있는 2를 제외하면 맨 앞의 3만 검색됩니다.

숫자라도 match는 String 타입을 지원하므로 문자형으로 '3.215' 만들어야

오류가 안 납니다.

 

지금까지 자바스크립트 정규표현식 중 Assertions에 대해 같이 알아보고 코딩해 봤습니다.

다음 포스팅은 자바스크립트 정규표현식 중 Groups에 대해 같이 공부해 봐요.

반응형