gigibean 2022. 11. 14. 22:44
728x90

🔑 키워드

정규식, 정규식을 자주 사용하는 메서드(match, replace, exac, test...)

❓ 정규식 사용하기

정규식은 한번 알아 놓으면 굉장히 유용하다.

정규식 사용법을 예제를 통해 알아보자

정규표현식

Anchors

beginning ^

문자열의 시작 혹은 여러 줄에서 멀티라인 플래그(m)을 사용할 때 라인의 시작 부분과 매칭한다.
즉 문자가 아니라 위치를 찾아야 할 때 사용한다.

문자열에서 맨 앞에 있는 문자(1개 이상)를 찾을 때
^\w+

she sells seashells

end $

문자열의 끝, 혹은 멀티라인 플래그(m)을 사용할 때 라인의 끝을 매칭한다.
해당 문자 또한 문자가 아니라 위치를 찾아야할 때 사용한다.

문자열에서 맨 뒤에 있는 문자를 찾을 때
\w$

she sells seashells

word boundary \b and not word boundary \B

\b : 문자열 내에서 문자 바운더리와 매칭한다.
\B : 반대로 바운더리가 아닌 부분과 매칭한다.

문자열에서 문자 처음에만 대문자로 만드는 작업을 할 때 첫문자을 찾기 위해서
/\b\w/g

she sells seashells

Quantifiers & Alternation

plus +

앞의 토큰이 1개 혹은 그 이상일 때 매칭

문자열에서 b문자가 앞에 오고, 이후 문자가 1개 이상인 경우를 찾을 때
/b\w+/g

b be beeerrrr

  • 위에 식에서는 + 를 사용하였으므로 1개 이상의 문자열이 뒤에 와야하기 때문에 b는 정규식에 매칭되지 않는다

star *

앞 토큰이 0개 혹은 그 이상일 때 매칭

문자열에서 b문자가 앞에오고, 이후 문자가 0개 이상인 경우를 찾을 때
/b\w*/g

b be beeerrrr

  • 이때는 * 을 사용하기 때문에 \w에 해당하는 값이 0개이더라도 매칭되기에 b 또한 정규식과 매칭된다.
문자열에서 특정 문자열이 0개 이상인 경우를 찾을 때
/(ab)+/g

abababab abbbbb

  • () 를 사용하여 캡처된 문자열을 사용할 수 있다.

quantifier {n, m}

매칭되는 문자가 n 개 이상 m 개 이하일 때 매칭된다.

\w{2,} - 문자 2개 이상
\w(2, 4} - 문자 2개 이상 4개 이하
a(bc){2, 4} - a와 2개 이상 5개 이하의 bc 

optional ?

앞 토큰과 매칭되는 문자열이 0개 혹은 1개

/colou?r/g

color colour

lazy ?

위에서 사용되는 ?와 달리 해당 물음표는 앞에 다른 수를 세는 표현과 함께 오며 기존 탐욕적으로 모든 문자를 다 찾는 방식과 다르게 레이지하게 문자를 찾는다.

// 탐욕적으로 태그 토큰을 찾을 때 
/\<.+\>/

<div> hi div tag</div>

// 레이지하게 태그 토큰을 찾는다면
/\<.+?\>/g

<div> hi div tag</div>

 

alternation - | []

OR 연산자로 | 앞 혹은 뒤 토큰과 매칭되는 값을 찾는다.
혹은 [] 로 사용할 수 있다.

a(b|c)
a[bc]

Character classes

character set []

OR 연산자와 마찬가지로 [ABC] 라고 한다면 A혹은 B혹은 C를 의미한다.

/[aeiou]/g

glib vex

negated set [^]

캐릭터 셋과 반대로 하당 셋에 포함된 문자열이 아닌 모든 문자를 의미한다.

/[^aeiou]/g

apple

range [-]

[a-z] - a 부터 z 까지
[A-Z] - a 부터 Z 까지
[0-9] - 0 부터 9 까지

dot .

라인브레이크(\n, \r) 를 제외한 모든 문

word & not word \w \W

문자, 숫자, 언더바를 포함하는 모든 문자와 매칭
그반대의미의 \W 대문자를 사용하면 반대의 의미를 가짐

digit & not digit \d \D

whitespace & not whitespcae \s \S

스페이스, 탭, 줄바꿈과 매칭

Groups & References

capturing group ()

괄호 내에 있는 문자열은 해당 문자열에 매칭되는 부분 문자(열)을 기억해둘 수 있고, 이렇게 캡쳐된 문자를 정규식에서 재사용하거나 문자열 메서드에서 콜백함수 혹은 특수 교체 패턴으로 사용할 수 있다.

// 콜백 함수로 사용하는 경우
`javascript`.replace(/(java)(script)/, (match, p1, p2) => `${match}: ${p2}-${p1}`)
// javascript: script-java
특수 교체 패턴

String.prototype.replace() - JavaScript | MDN

 

// 특수 교체 패턴을 사용할 경우
`javascript`.replace(/(java)(script)/, `$2-$1`)
// script-java
"javascript".replace(/(java)script/, '$&')
// javascript

non-capturing group (?:)

여러 토큰들을 그룹화하여 사용하지만 캡처링하지는 않을 때 사용한다.

/(?:ha)+/g

hahaha haa hah!

위와 같이 그룹화는 되지만,

"hahaha haa hah!".match(/(?:ha)+/)


0 : "hahaha"
groups : undefined
index : 0
input : "hahaha haa hah!"
length : 1

캡처링은 되지 않는다.
그냥 그룹핑과 비교해보면 더 쉽게 알 수 있다.

"hahaha haa hah!".match(/(ha)+/)

0: "hahaha"
1: "ha"
groups: undefined
index: 0
input: "hahaha haa hah!"
length: 2

 

 

Lookahead  (?=)

이 또한 그룹 패턴으로 해당 그룹 내에 있는 패턴에 뒤에 올 때만 매칭된다.
더하여 해당 그룹내에 있는 패턴은 매칭 결과에 포함되지 않는다.

/\d+(?=px)/g


1pt 2px 3em 4px

 

 

negative lookahead (?!)

이 또한 그룹 패턴으로 해당 그룹 내에 있는 패턴이 뒤에 오지 않을 때만 매칭된다.
더하여 해당 그룹내에 있는 패턴은 매칭 결과에 포함되지 않는다.

 

/\d+(?!px)/g

 

1pt 2px 3em 4px

 

Lookbehind  (?<=)

이 또한 그룹 패턴으로 해당 그룹 내에 있는 패턴이 앞에 올 때만 매칭된다.
더하여 해당 그룹내에 있는 패턴은 매칭 결과에 포함되지 않는다.

/(?<=\d)px/g


1px fourpx

negative lookbehind (?<!)

이 또한 그룹 패턴으로 해당 그룹 내에 있는 패턴이 앞에 오지 않을 때만 매칭된다.
더하여 해당 그룹내에 있는 패턴은 매칭 결과에 포함되지 않는다.

/(?<!\d)px/g

 

1px fourpx 10px

 

Flags

  • g(global): 매칭되는 모든 항목을 찾는다 (기존에는 매칭되는 한개의 항목을 찾으면 끝남)
/d+(?=px)/g

1pt 2px 3em 4px

/d+(?=px)/

1pt 2px 3em 4px

  • m(multi-line) anchor(^ 또는 $)가 문자열 전체가 아닌, 줄 각각에 매칭하여 줄별로 정규식 패턴을 매칭시킬 수 있습니다
/^[A-Z]/m

hello

Hello

/^[A-Z]/

hello

Hello

  • i(insensitive) 대소문자 구분을 무시하고 매칭합니다
/abc/i

ABC

실습 예제

예제를 통해 정규식을 실제로 사용해보자

https://school.programmers.co.kr/learn/courses/30/lessons/12951

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

프로그래머스 문제 중에 JadenCase 문자열 만들기 이다.

모든 문자열 중에서 첫 번째 문자가 대문자이고 나머지 문자는 소문자인 문자열을 만드는 문제이다.

 

예를 들어

input: "3people unFollowed me",

output: "3people Unfollowed Me"

 

input: "for the last week"

output: "For The Last Week"

 

우선 문자열에서 1️⃣띄어쓰기로 구분되는 문자열 중 맨 앞자리 문자를 찾아서 2️⃣소문자라면 대문자로 만들어주면 된다.

 

1️⃣ 정규식으로 문자열 중 맨 앞자리 문자를 찾는다

띄어쓰기로 매칭되는 문자(맨처음 문자 포함) = word bounday \b 

"for the last week"

각 문자에 해당하는 정규식은 두가지 형태로 모두 찾을 수 있다.

1) 띄어쓰기로 매칭되는 문자와 맨처음 문자 모두 찾기

/((?<=\s)([a-z])|^([a-z]))/g
// positive lookbehind (?<= ): 앞에 위치한 토큰(띄어쓰기)과 일치하하나 그룹에 포함시키지는 않음
// OR oper ( | )
// anchor start ^
// capturing(grouping) ()

for the last week

 

2) 문자 바운더리 다음에 위치한 문자 모두 찾기

/\b([a-z])/g
// word boundary \b
// capturing(grouping) ()

for the last week

 

2️⃣ 이렇게 찾은 문자들을 대문자로 만들어주기

 

참고: replace 메서드 매개변수를 함수로 사용하기

  • 두번째 매개변수로 함수를 지정할 수 있다
  • 함수는 정규표현식 매치가 수행된 후 호출된다
  • 함수의 반환값은 교체될 문자열이 된다.. (참고: 윗쪽에서 언급된 특수 교체 패턴은 반환값에 적용되지 x)
  • 만약 정규표현식의 플래그로 글로벌(g)이 오는 경우, 함수는 매치될 때마다 계속 호출

 

결과

str.toLowerCase().replace(/\b([a-z])/g, (match) => match.toUpperCase())

match에 해당하는 값이 각각 f, t, l, w 이고, 해당값을 반환값(교체될 문자)으로 해당 값의 toUpperCase()로 대문자로 변환하여 반환

-> 'For The Last Week'

 

이와 같이 정규식을 통해 문제를 해결할 수 있다

🔖참고자료

https://regex101.com/r/cO8lqs/16

https://regexr.com/

https://chrisjune-13837.medium.com/정규식-튜토리얼-예제를-통한-cheatsheet-번역-61c3099cdca8

https://blog.rhostem.com/posts/2018-11-11-regex-capture-group

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/String/replace

반응형