[javascript] 정규표현식 객체와 매칭 함수 사용 방법 - RegExp match()

자바스크립트의 정규 표현식 객체

자바스크립트로 작성한 정규표현식은 별도의 개발 도구 없이 웹 브라우저 콘솔 창에서 코드를 실행해서 정규표현식 실행 결과를 확인할 수 있습니다.

자바스크립트는 정규 표현식을 내장 객체로 지원합니다. 정규 표현식 객체를 생성한 후, 문자열을 검색하는 메소드에 정규 표현식 객체를 인자로 삽입해서 정규 표현식 매칭을 합니다.

문자열을 검색하는 메소드 중에 정규 표현식을 위한 메소드가 있기 때문에 문자열을 검색하는 방식과 같은 방법으로 사용하면 됩니다.

먼저 매칭에 사용할 정규 표현식을 담을 객체를 생성해야 합니다. 정규 표현식 객체를 생성하는 방법은 2가지가 있습니다. 같은 정규표현식입니다.

const regex = new RegExp(“[abc]+\s”, “gi”);
const regex = /[abc]+\s/gi;

후자의 방법은 정규 표현식 문자열을 (쌍)따옴표로 감싸지 않고 시작과 끝부분에 슬래시(/)를 붙여 정규 표현식임을 표시합니다. 두 번째 “/” 뒤의 영문자는 정규 표현식 플래그(옵션) 표시입니다.

이 정규 표현식 표현을 리터럴 문자열이라고 하고, new 연산자로 생성하는 정규 표현식 객체와 동일합니다.


루프문 사용시 주의

정규 표현식 리터럴 문자열을 루프문 안에 작성하면 안됩니다. 루프를 돌 때마다 정규 표현식 객체를 재생성 하게 됩니다.


생성한 정규 표현식 객체는 객체의 내장 매칭 메소드(test(), exec()), 또는 문자열 객체 (string)가 제공하는 문자열 검색 메소드의 파라미터로 사용해 정규 표현식과 일치하는 문자(열)을 찾게 됩니다.

다음 정규표현식 선언 방식은 자바스크립트와 펄(Perl), PHP에서 정규표현식을 선언하는 방식입니다.

정규 표현식 객체에 내장된 메소드 사용 방법을 먼저 알아보겠습니다.

정규 표현식 객체에는 test()와 exec() 메소드 두 개가 문자열 매칭을 위해 제공됩니다. 두 메소드가 정규 표현식 매칭에 필요한 필수 기능을 제공하지만, 용도가 다소 제한적이어서 많이 사용되지는 않습니다.

메소드

기능

test()

문자열 안에 정규 표현식과 매칭되는 문자(열)이 있는지를 true/false 반환 값으로 알려줍니다.

exec()

문자열 안에 정규 표현식과 매칭되는 첫 번째 문자(열)에 대한 정보를 배열로 반환합니다. 정규 표현식 객체 안에는 마지막으로 매치한 문자열의 다음 위치를 기억하는 lastIndex 속성이 있어서 다음 번 매칭할 때는 마지막 매칭한 이후의 나머지 문자열에 대해서만 매칭이 이루어집니다.

정규 표현식 내장 메소드로 매칭하기

정규 표현식 객체체에 내장된 메소드(들)중 문자열을 매칭하는데 사용하는 메소드는 test(), exec() 2개이며 기초 사용방법은 다음과 같습니다.

test()

test() 메소드는 정규 표현식과 매칭되는 문자(열)이 있는지 확인만 합니다.

const str = `그래서 나는 밤이 지새도록 나의 사랑, 나의 사랑, 나의 생명, 나의 신부 곁에 누워만 있네.`
const regex = /나의\s(사랑|생명|신부)/
const ret = regex.test(str); // true

exec()

exec() 메소드는 반환된 결과를 사용하는 방법이 다소 번거롭습니다.

정규 표현식으로 문자열 검색 및 매칭을 할 때는 exec() 보다는 문자열 객체의 검색 메소드를 사용하는 것이 더 좋습니다.

const str = `그래서 나는 밤이 지새도록 나의 사랑, 나의 생명, 나의 신부 곁에 누워만 있네.`
const regex = /나의\s(사랑|생명|신부)/g
const ret = regex.exec(str);

exec() 메소드 사용시 주의

exec()으로 매칭 결과를 얻을 때는 정규 표현식에 플래그(옵션) “g”를 사용해야 합니다.
“g” 플래그 없이 정규 표현식 매칭을 하면 exec() 메소드를 반복 실행해도 문자열의 맨 처음 매칭되는 문자열 정보만 똑같이 반환합니다. 정규 표현식 객체의 lastIndex 값 또한 0만 반환됩니다. 항상 “g” 플래그 사용에 주의해야 합니다.

 

exec()으로 매칭 후 반환되는 결과 배열은 다음과 같습니다.

[0]: “나의 사랑”
[1]: “사랑”
groups: {type: ‘사랑’}
index: 15
input: “그래서 나는 밤이 지새도록\n나의 사랑, 나의 사랑, 나의 생명, 나의 신부 곁에 누워만 있네.”
length: 2

exec()의 실행 결과로 반환되는 결과 배열에 포함된 항목들은 다음과 같이 구성됩니다. 입력 문자열에서 처음 매칭된 문자(열)의 정보가 반환된다는 점에 주의해야 합니다.

다음 번 exec()을 실행할 때 마지막으로 매칭된 위치를 기억해서 매칭을 이어서 할 수 있도록 입력 문자열의 위치를 기억하는 lastIndex 속성이 정규 표현식 객체에 존재합니다.

앞의 exec() 결과에서 index가 매칭 문자열의 시작 위치를 가리키기 때문에 “index + 문자열 길이”인 20이 lastIndex 값이 됩니다.

[0]: 매칭된 문자열
[1~n]: 정규 표현식의 캡처 그룹 문자열 배열 요소
index: 입력 문자열의 매칭 시작 위치
indices: 매칭된 캡처 그룹 문자열의 시작과 끝 인덱스(들)을 담은 배열
input: 입력 문자열
length: 배열의 길이(매칭된 문자열 + 캡처 그룹 문자열(들) 배열)
groups: 네임드 캡처 그룹 이름:값 쌍(들)로 구성된 객체

exec()를 사용해서 문자열에서 정규 표현식과 매칭되는 모든 매칭 문자열에 대한 정보를 얻으려면 다음처럼 루프문으로 처리를 해야 합니다.

while ((ret = regex.exec(str)) !== null) {
    console.log("Matched string is "+ret[0]+", Next match starts at "+regex.lastIndex)
}

콘솔출력
--------
Matched string is 나의 사랑, Next match starts at 27
Matched string is 나의 생명, Next match starts at 34
Matched string is 나의 신부, Next match starts at 41

더 이상 매칭되는 결과가 없으면 exec()는 null을 반환합니다. 정규표현식을 다이어 그램으로 표현하면 다음과 같습니다.

 

마지막 exec()로 매칭이 되면 매칭된 문자(열)의 다음 위치를 정규 표현식 객체의 lastIndex 속성이 보관하고 있습니다. exec()로 더 이상 매칭이 되지 않으면 last Index 속성 값은 0으로 초기화 됩니다.

문자열 검색 메소드로 매칭하기

문자열 객체의 메소드(들)은 기본적으로 정규 표현식을 검색 문자열로 사용할 수 있습니다.

match() 메소드는 정규 표현식과 매치되는 문자열(들)을 배열로 반환합니다. 비교적 사용 빈도가 높은 메소드입니다.

match()

정규 표현식이 강력한 힘을 발휘할 때는 특정 조건에 맞는 패턴의 문자열을 모두 찾고 싶을 때입니다. 이럴 때 match() 메소드를 사용합니다.

const str = `그래서 나는 밤이 지새도록
나의 사랑, 나의 생명, 나의 신부 곁에 누워만 있네.`

 

문자열에서 “사랑”이라는 단어를 match() 메소드에 파라미터 값으로 대입하면 “사랑”과 일치하는 첫 번째 문자열, 즉 “사랑” 이라는 단어 1개를 요소로 가진 배열을 반환합니다.

const ret = str.match("사랑"); // ["사랑"]

 

match() 메소드는 정규 표현식으로 찾고자 하는 문자열 패턴을 사용하지 않으면 아무 의미 없는 결과만을 반환합니다.

match() 메소드로 문자열 검색을 할 때는 정규 표현식을 사용해서 원하는 패턴의 문자열을 찾아야 합니다. 실제로 match() 메소드는 파라미터 값으로 일반 문자열이 넘어오면 내부에서 정규 표현식으로 변환을 합니다.

앞서의 match(“사랑”)은 다음과 완전히 같습니다.

str.match(/사랑/);

 

정규 표현식을 사용해서 “나의 **” 패턴에 맞는 정규 표현식을 만들어 조건에 맞는 모든 문자열을 찾도록 매치를 해 보겠습니다.

const regex = /나의\s.{2}/g;
str.match(regex); // ['나의 사랑', '나의 생명', '나의 신부']

 

match() 메소드가 반환하는 결과는 정규 표현식 패턴과 일치하는 문자(열)의 배열 입니다.

replaceAll()

자바스크립트에 replace() 메소드만 있어서 전체 문자열 안에서 바꾸기를 할 수 없었던 시기에는 정규 표현식을 활용해서 replaceAll() 메소드와 같은 기능을 만들어 사용했습니다.

replaceAll() 메소드는 replace() 와 정규 표현식으로 다음과 같이 표현할 수 있습니다.

string.replace(/찾는문자열/g, “바꿀문자열”);