Search

반응형

'regexp'에 해당되는 글 2건

  1. 2022.12.24 [자바스크립트]정규표현식 어썰션, Assertions
  2. 2022.11.28 [자바스크립트]정규표현식 만드는 방법, 정규식, regular expression 1
반응형

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

자바스크립트 정규표현식(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에 대해 같이 공부해 봐요.

반응형
반응형

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

프로젝트를 하다 보면 가끔 정규표현식(정규식 또는 regular expression) 코드를 만나게 됩니다.

개발자로 코딩을 하면서 사실 정규표현식을 자주 접하지는 않고

깊이 공부한 적이 없기에 복잡한 특수 문자들을 보면 뇌 정지가 오곤 합니다.

그래도 개발자로 코딩시 잘 활용하면 편하게 사용할 수 있기에

자바스크립트 정규 표현식을 어떻게 사용하는지

그 방법에 대해 최대한 쉽게 설명해보겠습니다.

 

정규표현식이란?

문자열 내 특정한 패턴을 찾을 수 있는 표현식입니다.

또한 문자열이 정해진 패턴대로 만들어졌는지 확인할 수도 있습니다.

예를 들어 전화번호, 이메일 주소, 홈페이지 주소 등 규격에 맞게 값을 넣을 수 있도록

입력값을 체크하는 경우에도 유용하게 사용할 수 있습니다.

하지만 막상 정규표현식(정규식)을 코딩 개발 시 사용하려면 어렵기도 하고

어떻게 만들고 읽고 해석해야 하는지 막막한 경우가 있더군요.

그래서 왕초보도 따라할 수 있게 최대한 쉽게 설명도 하고

예제도 만들어서 프로젝트 개발에 도움이 되길 기대해봅니다.

 

무엇이 필요할까요?

자바스크립트에서 정규표현식을 사용하기 위해서는

무엇이 필요한지 볼까요?

  • 체크할 대상(문자열, 이메일, 전화번호 등)
  • 체크에 사용할 패턴과 플래그(옵션)
  • 패턴과 플래그를 담을 변수 또는 객체

 

기본 사용법.

먼저 문자열, 이메일, 전화번호 등 체크할 대상을 정해야 합니다.

그렇다면 문자열로 가볍게 시작해 볼까요?

다음,

패턴이 필요합니다.

패턴을 만드는 것은 많이 복잡할 수 있습니다. (특수 문자 등..)

우선 간단한 패턴 하나로 시작해볼게요.

플래그(옵션)도 선택해서 패턴과 같이 조합해 볼 수 있지만 우선은 패턴 먼저 사용해봅니다.

패턴이 정해지면 패턴을 담을 변수(또는 객체)를 선언하고 할당합니다.

그리고 RegExp에서 상속받은 내장 메서드를 사용해서

패턴을 적용 및 사용해 봅니다.

정규표현식은 리터럴을 사용하거나

RegExp() 생성자를 통해서 객체로 만들어 사용할 수 있습니다.

 2가지 방식 중 먼저 리터럴 방식으로 패턴을 만들어 코딩 예제를 만들어볼게요.

 

정규표현식 리터럴로 사용하기.

직접 변수에 패턴을 할당해서 사용하는 방법입니다.

패턴은 /(슬래시)로 시작해서 /(슬래시)로 닫으면 됩니다.

/와 / 사이의 문자들을 패턴으로 인식하게 된다는 의미입니다.

패턴 시작 /

패턴 a

패턴 종료 /

플래그 (옵션)

여기서 플래그는 패턴 종료 슬래시 뒤에 붙여서 사용합니다.

 

예제를 통해 같이 리터럴 정규식을 만들어 보겠습니다.

1. myReg1 상수에 처음 만나는 글자 a 하나만 찾는 패턴을 만든다.

const myReg1 = /a/;

2. myReg2 상수는 처음 만나는 글자 k 하나만 찾는 패턴을 만든다.

const myReg2 = /k/;

두 상수에 할당된 패턴에는 문자열을 나타내는 따옴표가 없다는 것을 잘 확인한다!!!

3. 테스트를 위해 sampleTxt1 변수를 선언하고 샘플 문자열 'abc alphabet'을 할당한다.

const sampleTxt1 = 'abc alphabet';

4. sampleTxt1 문자열에 'a'가 있는지 확인을 하기 위해 정규표현식(RegExp)의

내장 메서드인 test()를 사용하면 된다. ('a'가 하나라도 있으면 true, 전혀~없으면 false)

console.log(myReg1.test(sampleTxt1));   // a가 있으니 true

console.log(myReg2.test(sampleTxt1));  // k가 없으니 false

 

크롬브라우저 F12 Console 에서 테스트

 

지금까지 리터럴을 사용해서 정규표현식을 만들고 코딩해봤습니다.

true/false가 아닌 일치하는 값을 받아보는 코딩을 RegExp의 exec() 메서드로 해보겠습니다.

1. 패턴과 일치하는 정보를 배열로 받기 위해서 smpArr 변수를 선언한다.

let smpArr;

2. 패턴에 매칭되는 정보를 배열에 담는다. exec() 리턴 타입은 Array다.

smpArr = myReg1.exec(sampleTxt1);

3. smpArr값을 출력한다. 배열이기에 [0] 인덱스를 사용할 수 있다.

console.log(smpArr);   //['a', index: 0, input: 'abc alphabet', groups: undefined]

console.log(smpArr[0]);   // a

console.log(ampArr.index);  // 5   a의 첫 번째 위치가 출력된다.

지금까지 리터럴을 사용해서 정규표현식을 만드는 방법에 대해 알아봤습니다.

 

new RegExp() 객체 생성자 사용하기.

RegExp()는 자바스크립트에서 정규표현식의 객체를 만들어 주는 생성자입니다.

생성자는 함수이며 객체를 만들 때 사용합니다.

변수를 선언해서 패턴을 할당하는 리터럴 방식과는 다르게

new 키워드를 사용해서 RegExp()의 새로운 객체를 만드는 방법으로 사용합니다.

그럼 new RegExp()를 사용해 정규표현식(정규식) 패턴 객체를 같이 코딩하며 만들어 볼까요?

1. 객체를 담을 변수를 선언하고 new 키워드로 객체를 생성합니다.

var reObj = new RegExp();

2. 객체는 만들었는데 패턴이 없네요. 패턴을 만드는 방법은 두 가지가 있습니다.

처음 생성자 인자로 패턴을 넣는 방식과 객체에 패턴을 할당하는 방식이 있습니다.

var reObj = new RegExp('s');  또는 var reObj = new RegExp(/s/);

인자로 넘기는 경우는 따옴표나 슬래시 둘 다 가능합니다.

reObj = /s/;

이렇게 객체에 패턴을 직접 할당할 수 있습니다. 당연히 슬래시만 가능합니다.

이렇게 객체를 사용하는 경우는 런타임에 컴파일 되기 때문에

외부에서 패턴을 가져오거나 동적으로 생성할 때 유용합니다.

const pattern = /a/;

const reObj = new RegExp(pattern);

const text = 'My name is sophia';

consloe.log(reObj.exec(text));

 

우리는 이제 자바스크립트에서 정규 표현식을 만들고 사용하는 방법에 대해 알게 되었습니다.

리터럴로 값을 할당해서 사용하는 방법과

new RegExp()로 패턴 객체를 만들어 사용하는 방법

2가지에 대해 알게 되었습니다.

우리는 패턴으로 아주 간단하게 /a/를 사용했지만

실제 특수 문자등을 포함해서 다양한 패턴을 만들 수 있습니다.

또한 플래그 옵션으로 더 풍부한 기능을 사용할 수 있습니다.

다음 포스팅에서 다양한 패턴과 옵션을 어떻게 사용하는지

다양한 예제를 통해 알아보고 자바스크립트 정규표현식을 마스터해보겠습니다.

즐 코딩하세요.

 

반응형