이번 시간에는 string 문자나 정규표현식을 정규표현식으로 변경해주는 코드를 살펴보자
1. 언제 유용할까?
- string 문자(
’feat’
) 혹은 string 타입의 정규표현식(’/feat/’
)은 정규표현식 함수를 바로 쓸 수 없다. - 그렇기 때문에 string타입의 문자 혹은 정규표현식을 정규표현식으로 변환해야하는데, 어떤 경우에 변환하는 코드를 쓰는 걸까?
- 대체로 입력값을 string 타입만 받을 수 있는 경우일 것이다.
- 대표적으로 github actions의 경우, 인자를 string으로만 받을 수 있기 때문에 github actions에서 입력값으로 정규표현식을 받으려면
‘/feat/’
형태로 써야한다. - 하지만
‘/feat/’
형태로 받으면 정규표현식 함수를 쓸 수 없다.
🤔 왜 string타입의 정규표현식은 바로 쓸 수 없을까?
- 그 이유는
typeof
를 해보면 쉽게 알 수 있는데, 문자는 타입이 string이지만 정규표현식은 타입이 object이다. - 이 말은 곧 정규표현식을 string타입으로 선언하면 사용할 수 없다는 뜻이 된다.
const string = '/feat/';
const regex = /feat/;
console.log(typeof string, typeof regex)
🚫
new RegExp()
는 string을 받아서 정규표현식으로 바꿀 수 있는데, 이걸 사용하면 안될까? 안된다!
'/feat/'
을new RegExp('/feat/')
로 하면/feat/
가 나올 거 같지만 결과는 그렇지 않다.
const string = '/feat/';
console.log(new RegExp(string))
🏃🏻 그럼 변환 코드는 어떻게 구성해야할까? 본격적으로 코드를 살펴보자
2. string을 정규표현식으로 변환하기
1) 전체 코드보기
convertToRegExp(string타입_정규표현식)
형태로 사용하면 된다.
function convertToRegExp(text) {
if (text.match(/^\/.+\/[gmixXsuUAJ]*$/)) {
return regexParser(text);
} else return new RegExp(text, 'g');
}
function regexParser(text) {
const m = text.match(/(\/?)(.+)\1([a-z]*)/i);
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) {
return RegExp(text);
} else {
return new RegExp(m[2], m[3]);
}
}
- 사용한 모습은 아래와 같다.
console.log(convertToRegExp('feat')) // /feat/
console.log(convertToRegExp('/^[a-z]/i')) // /^[a-z]/i
2) 코드 상세보기
(1) convertToRegExp함수
🛠️
convertToRegExp()
는 word가 string 혹은 string 정규표현식인지 체크하여, 정규표현식으로 변환한다.
function convertToRegExp(word) {
if (word.match(/^\/.+\/[gmixXsuUAJ]*$/)) { // [1]
return regexParser(word); // [2]
} else return new RegExp(word, 'g'); // [3]
}
[1]
: word가 /
로 시작하고 /
로 끝나며, 만약 flag(/g
, /i
등)을 가지는지 체크한다.
: /^\/.+\/[gmixXsuUAJ]*$/
정규표현식을 자세히 보면 의미는 아래와 같다.
[2] 만약 string형태의 정규표현식이면 regexParser()
를 사용해 변환된 정규표현식을 리턴한다.
[3] string 형태의 문자라면 new RegExp
을 사용해 정규표현식을 한다.
(2) regexParser함수
🛠️
regexParser()
에서는 string 정규표현식을 정규표현식으로 변경한다.
function regexParser(word) {
const m = word.match(/(\/?)(.+)\1([a-z]*)/i); // [1]
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) { // [2]
return RegExp(word);
} else {
return new RegExp(m[2], m[3]); // [3]
}
}
[1]
: 주어진 word가 정규식에 매치되는 경우를 array로 보여준다.
const m = word.match(/(\/?)(.+)\1([a-z]*)/i); // [1]
: /(\/?)(.+)\1([a-z]*)/i
는 자세히 보면 아래와 같다.
: 만약 word에 /feat/
를 넣고, m을 출력해보면 아래와 같이 나타난다.
[2]
: 유효치 않은 flag를 가진 정규표현식인 경우에 RegExp(word)
를 한다.
if (m[3] && !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])) { // [2]
return RegExp(word); // [2]
}
: m[3]
의 경우, 시작/
가 있고 마지막 /
뒤에 문자가 있는 경우에 존재한다. (ex. /feat/g, /ass/hhhh)
: 만약 word에 '/^hi$/i'
가 넣으면 m은 아래와 같은 형태가 된다.
: !/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(m[3])
은 유효치 않은 flag인지 체크한다.
// ex. 유효치 않은 flag를 쓴 형태
/ass/h // h flag는 존재하지 않음
/asdadccc/ssf // ssf flag는 존재하지 않음
[3] 유효한 정규표현식 형식인 경우 new RegExp(m[2], m[3])
를 사용해 정규표현식을 만든다.
...
else {
return new RegExp(m[2], m[3]); // [3]
}
'이번엔 이 공부 끝내겠다 시리즈 > 정규표현식' 카테고리의 다른 글
js 정규표현식 기초 (1) | 2021.09.10 |
---|
댓글