정규표현식

hackney·2021년 6월 18일

프로그래머스에서 정규표현식과 함께 match( ) 를 사용해본 이후 조금 더 알아보고자 mdn과 드림코딩,ko.javascript.info 를 이용해 개념을 살펴보았다 그 중 메소드와 함께 사용되어지는 정규표현식을 3가지 먼저 정리해보았다~!


정규 표현식(regular expression)은 문자 검색과 교체에 사용되는 패턴.
자바스크립트에서 정규 표현식 또한 객체.

  • RegExp 의 exec( ), test( )
  • String 의 match( ), replace( ), search( ), split( )

과 함께 사용된다.


정규표현식 만들기 (2가지 방법)

[RegExp 객체의 생성자 함수 호출 방법]

var regexp = new RegExp("pattern", "flags");

생성자 함수를 사용하면 정규식이 실행 시점에 컴파일된다.
정규식의 패턴이 변경될 수 있는 경우, 혹은 사용자 입력과 같이 다른 출처로부터 패턴을 가져와야 하는 경우에는 생성자 함수를 사용!

[정규식 리터럴 (/ 슬래쉬로 감싸는 패턴)]

var regexp = /pattern/; -> 플래그가 없음. var regexp = /pattern/gmi; -> 플래그g,m,i가 있다.

정규식 리터럴은 스크립트가 불러와질 때 컴파일되기때문에 만약 정규식이 상수라면 위처럼 사용하는 것이 성능을 향상시킬 수 있음.

슬래시 "/"는 자바스크립트에게 정규 표현식을 생성하고 있다는 것을 알려줌.
문자열에 따옴표를 쓰는 것과 동일한 역할.
짧은 문법을 사용하던 긴 문법을 사용하던 상관 없이 위 예시에서의 regexp
내장 클래스 RegExp의 인스턴스가 된다.

두 문법의 중요한 차이점은 /.../를 사용하면 문자열 템플릿 리터럴에서 ${...}를 사용했던 것처럼 중간에 표현식을 넣을 수 없다는 점. 슬래시를 사용한 방법은 완전히 정적이다.
슬래시를 사용한 짧은 문법은 코드를 작성하는 시점에 패턴을 알고 있을 때 사용한다. 아마 대다수가 이런 경우에 속한다.
반면 new RegExp를 사용한 긴 문법은 ‘상황에 따라’ 동적으로 생성된 문자열을 가지고 정규 표현식을 만들어야 할 때 주로 사용한다. 관련 예시를 살펴보자.

let tag = prompt("어떤 태그를 찾고 싶나요?", "h2");
let regexp = new RegExp(`<${tag}>`); 
// 프롬프트에서 "h2"라고 대답한 경우, 
// /<h2>/와 동일한 역할을 합니다.

패턴과 플래그

정규 표현식은 패턴 (pattern)과 선택적으로 사용할 수 있는 플래그 (flag) 로 구성된다.

🔎 패턴

단순 패턴 사용하기

단순 패턴은 문자열을 있는 그대로 대응시키고자 할 때 사용된다.
/abc/ → 정확하게 'abc'라는 문자들이 모두 함께 순서대로 나타나야함.

-> "Hi, do you know your abc's?"
-> "The latest airplane designs evolved from slabcraft."

특수 문자 사용하기

검색에서 하나 이상의 b들을 찾거나, 혹은 공백을 찾는 것과 같이 '있는 그대로의 대응' 이상의 대응을 필요로 할 경우, 패턴에 특수 문자를 포함시킨다.

예를 들어 /abc/ 패턴은 'a' 문자 뒤에 0개 이상의 'b' 문자 ( 문자는 바로 앞의 문자가 0개 이상이라는 것을 의미함) 가 나타나고 바로 뒤에 'c' 문자가 나타나는 문자 조합에 대응된다.
-> "cbbabbbbcdebc,"

자주 사용하는 특수문자

그룹과 범위지정

| 또는
() 그룹
[] 문자셋, 괄호안의 어떤 문자든
[^] 부정 문자셋, 괄호안의 어떤 문가 아닐때
(?:) 찾지만 기억하지는 않음

수량

? 없거나 있거나 (zero or one)
* 없거나 있거나 많거나 (zero or more)
+ 하나 또는 많이 (one or more)
{n} n번 반복
{min,} 최소
{min,max} 최소, 그리고 최대

경계 타입

\b 단어 경계
\B 단어 경계가 아님
^ 문장의 시작
$ 문장의 끝

문자 클래스

\ 특수 문자가 아닌 문자
. 어떤 글자 (줄바꿈 문자 제외)
\d digit 숫자
\D digit 숫자 아님
\w word 문자
\W word 문자 아님
\s space 공백
\S space 공백 아님

🚩 플래그

정규 표현식엔 검색에 영향을 주는 플래그를 선택적으로 붙일 수 있음.

자바스크립트는 6개의 플래그를 지원한다.

보통 g와 m을 많이 사용함.

i

i 플래그가 붙으면 대·소문자 구분 없이 검색합니다. 따라서 A와 a에 차이가 없다.(아래 예시 참조).

g

g 플래그가 붙으면 패턴과 일치하는 모든 것들을 찾습니다. g 플래그가 없으면 패턴과 일치하는 첫 번째 결과만 반환된다.

m

다중 행 모드(multiline mode)를 활성화 함.

s

.이 개행 문자 \n도 포함하도록 ‘dotall’ 모드를 활성화함.

u

유니코드 전체를 지원합니다. 이 플래그를 사용하면 서로게이트 쌍(surrogate pair)을 올바르게 처리할 수 있음.

y

문자 내 특정 위치에서 검색을 진행하는 ‘sticky’ 모드를 활성화 시킨다.


str.match( )

str.match(regexp) 를 호출하면 str에서 regexp와 일치하는 것들을 찾아낸다.
str.match에는 3가지 모드가 있음.

  1. 정규 표현식에 플래그 g가 붙으면 패턴과 일치하는 모든 것을 담은 배열을 반환.
    대,소문자 구분 없이 검색할 수 있도록 하는 플래그 i를 사용해서 rose와 Rose가 반환되었음.
let str = "Rose is rosy, Rosy loves you";

alert (str.match(/rosy/gi)); // rose,Rose   
  1. 플래그 g가 붙지 않는 경우에는 패턴에 맞는 첫 번째 부분 문자열만 담은 배열을 반환한다. 해당 문자열은 배열 인덱스 0에 저장되고 이 문자열의 프로퍼티에는 상세한 추가 정보가 저장된다.
let str = "Rose is rosy , Rosy loves you";
let result = str.match(/rosy/i); //g플래그 없음.

alert(result[0]); // rosy
alert(result.length); // 1

//Details:
alert (result.index); // 0 (부분 문자열의 위치)
alert (result.input); // "Rose is rosy , Rosy loves you"(원본문자열)
  1. 플래그 g의 유무와 상관없이 패턴과 일치하는 부분 문자열을 찾지 못한 경우에는 null이 반환된다.
    일치하는 부분 문자열이 없는 경우에는 빈 배열이 아닌 null을 반환한다는 점은 아주 중요한 차이점이다. 이전에 프로그래머스 문제에서도 이 부분을 다시 생각해봐야했었다 ㅎㅎ
    (null일 경우 length 프로퍼티를 사용할 수 없음)
let matches = "JavaScript".match(/HTML/); // matches엔 null이 저장됨

if (!matches.length) { // TypeError: Cannot read property 'length' of null
  alert("바로 윗줄에서 에러가 발생합니다.");
}

str.match( ) 의 호출 결과가 항상 배열이 되게 하려면 아래처럼 작성.

let matches = "JavaScript".match(/HTML/) || [];

if (!matches.length) {
  alert("정규 표현식과 일치하는 부분 문자열이 없습니다."); // 이제 에러없이 잘 동작하네요.
}

str.replace( )

메소드 str.replace(regexp, replacement)를 사용하면 str 내 부분 문자열 중 regexp에 일치하는 부분 문자열을 replacement로 교체할 수 있다. 이때 플래그 g가 있으면 모든 부분 문자열이 교체되고, 그렇지 않으면 첫 번째 부분 문자열만 교체된다.

// 플래그 g 없음.
alert ("Rose is rosy,rosy".replace(/rosy/i,"Jenny"));
//"Rose is Jenny,rosy"

// 플래그 g 있음.
alert ("Rose is rosy,rosy".replace(/rosy/gi,"Jenny"));
//"Rose is Jenny,Jenny"

여기서 두 번째 인수 replacement는 문자열인데, 문자열 안에 다음과 같은 특수 문자를 넣어주면 독특한 방식으로 문자열 교체가 가능하다.

// $& 사용 예시
alert( "I love HTML".replace(/HTML/, "$& and JavaScript") ); // I love HTML and JavaScript

regexp.test( )

패턴과 일치하는 부분 문자열이 하나라도 있는 경우 메소드 regexp.test(str) 을 호출하면 true 가 그렇지 않으면 false가 반환된다.

let str = "I love JavaScript";
let regexp = /LOVE/i;

alert( regexp.test(str) ); // true

출처: https://ko.javascript.info/regexp-introduction

profile
우리 머릿속에 어떤 생각이 차지하고 있든 우주의 질서가 달라지지는 않는다

0개의 댓글