알아두면 조금 쓸데있는 VSC를 위한 정규표현식 치환
왜 정규표현식을 사용하는가?
어떤 문자열이 올바른 이메일인지 어떻게 알 수 있을까요? 실제로 메일을 보내고 그 내용을 사용자가 받아보았는지 확인하는 방법도 있겠지만 보내기 전에 이메일이 어느정도 올바른 형식인지 확인할 수 있으면 더 좋을 것입니다. 예를 들어 qwerty
는 굳이 이메일을 보내지 않아도 유효한 이메일이 아님을 알 수 있습니다. 그 이유는 이메일은 특정한 형식을 만족하기 때문입니다. 1
^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$
JavaScript의 경우 위와 같은 특수한 문자열을 이용해 문자열이 적어도 올바른 이메일이 되기 위한 형식을 갖추었는지 확인할 수 있습니다. 직접 여러 문자 열을 넣어 확인해보고 싶다면 다음 사이트를 방문하시면 됩니다.
정규표현식
위에서 말한 특수한 문자열을 정규표현식(Regular expression; RegEx)이라고 부릅니다. 정규표현식이란 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 사용되는 형식 언어입니다. 이는 문자열을 검색, 대체, 추출하는데 사용되는 강력한 도구로, 특수한 문법을 통해 문자열 내에서 원하는 패턴을 찾을 수 있습니다. 프로그래밍 언어나 텍스트 편집기에서 주로 적용되어 데이터 검증, 웹 스크래핑 및 텍스트 처리와 같은 다양한 분야에 활용됩니다.
정규표현식에 대해서 구체적인 예시로 이해하고 싶으신 분을 위해서 MDN에서도 추천하는 단계적으로 정규표현식을 학습할 수 있는 사이트를 소개해드립니다.
본 글은 코드를 수정하는 과정에서 정규표현식을 이용해 단순 노동을 줄이기 위한 방법을 소개합니다.
Visual Studio Code에서 정규표현식을 이용해 치환하기
Visual Studio Code(VSC)는 널리 사용되는 소스코드 편집기로 제가 VSC를 사용하기 때문에 본 문서에서는 VSC를 기준으로 설명하게 되었습니다.
하지만 다음 문서에서 설명하듯 다른 편집기에서도 정규표현식을 이용한 치환이 가능하니 참고하시길 바랍니다. 소개되지 않은 편집기를 사용하신다면 추가적으로 검색해보시길 추천드립니다.
기초적인 사용법
Ctrl+F
를 누르면 문자열을 검색할 수 있는 창이 나옵니다. 검색 창 왼쪽에 있는 오른쪽 화살표 버튼을 누르면 문자열을 치환할 수 있는 창이 나옵니다. 이때는 단순히 한 문자열을 다른 문자열로 바꾸는 역할을 하기 때문에 바꾸는 대상을 정규표현식으로 표현하기 위해서는 다음과 같이 .*
과 유사하게 생긴 아이콘을 눌러야 합니다. 그러면 VSC가 Find
에 적힌 문자열을 정규표현식으로 인식합니다.
정규표현식 치환을 사용하기 위해서는 Find
에 정규표현식을 입력하고 Replace
에 치환할 문자열을 입력합니다. 그 후 Replace
또는 Replace All
을 누르면 모든 문자열이 치환됩니다. 정규표현식을 이용한 치환도 Ctrl+z
등을 통한 방법으로 되돌릴 수 있으므로 편하게 시도해보셔도 됩니다.
다만 정규표현식을 이용한 치환은 문서 전체에 영향을 미치기에 특히 문서가 긴 경우 주의하시길 바랍니다. Find
에 정규표현식을 입력한 후 에디터 상에서 정규표현식에 의해 강조된 문자열이 모두 원하는 문자열인지 확인하시길 바랍니다.
이러한 문제를 줄이기 위해 선택된 영역만 치환하는 기능을 찾아보았으나 이에 대한 버그를 신고하는 Github 이슈가 있다는 점을 사용하실 때 참고해주시기 바랍니다.
Visual Studio Code를 위한 정규표현식 문법 배우기
Visual Studio Code를 위한 정규표현식 문법을 배우기 위해서는 설명이 빈약한 Visual Studio 관련 문서보다는 다음의 Visual Studio 관련 문서를 추천 드립니다. 비록 Visual Studio 관련 문서이지만 Visual Studio Code의 정규표현식과 유사한 점이 많기에 초반 학습에 참고하시길 바랍니다. Visual Studio와 Visual Studio Code의 정규표현식 엔진 차이에 대한 StackOverflow 질문도 첨부해드리니 차이점을 이해하여 올바르게 이용하시면 좋겠습니다.
예시
예시 상황과 이에 적용할 수 있는 정규표현식 예시를 제공하였습니다.
이를 위해 다음과 같은 정규표현식 치환을 사용한다.
문장 다음에 나오는 정규표현식은 다음과 같은 형식입니다.
Find에 입력해야 할 정규표현식
Replace에 입력해야 할 정규표현식
일부분 남기기
도겸은 학교 교과목을 분류하는 프로그램을 리팩토링하였다. 리팩토링 과정에서 코드 일부를 짧게 만들 수 있게 되어 다음과 같이 수정하고 싶다.
기존 코드는 다음과 같다.
{
all: new LecsExpr(this.lectures),
dept: new LecsExpr(union(this.lectures, this.lecture.all)),
기필: new LecsExpr(union(this.lectures, this.lecture.기필)),
기선: new LecsExpr(union(this.lectures, this.lecture.기선)),
전필: new LecsExpr(union(this.lectures, this.lecture.전필)),
전선: new LecsExpr(union(this.lectures, this.lecture.전선)),
심전필: new LecsExpr(union(this.lectures, this.lecture.심전필)),
연구: new LecsExpr(union(this.lectures, this.lecture.연구)),
}
이를 다음과 같이 바꾸고 싶다.
{
all: this.lectures,
dept: union(this.lectures, this.lecture.all),
기필: union(this.lectures, this.lecture.기필),
기선: union(this.lectures, this.lecture.기선),
전필: union(this.lectures, this.lecture.전필),
전선: union(this.lectures, this.lecture.전선),
심전필: union(this.lectures, this.lecture.심전필),
연구: union(this.lectures, this.lecture.연구),
}
이를 위해 다음과 같은 정규표현식 치환을 사용한다.
new LecsExpr\((.+)\)
$1
일부분 남기기2
도겸은 학교 교과목을 분류하는 프로그램을 다시 한 번 리팩토링하였다. 이를 위해 코드 일부를 다음과 같이 수정하고 싶다.
기존 코드는 다음과 같다.
{
all: this.lectures,
dept: union(this.lectures, this.lecture.all),
기필: union(this.lectures, this.lecture.기필),
기선: union(this.lectures, this.lecture.기선),
전필: union(this.lectures, this.lecture.전필),
전선: union(this.lectures, this.lecture.전선),
심전필: union(this.lectures, this.lecture.심전필),
연구: union(this.lectures, this.lecture.연구),
}
이를 다음과 같이 바꾸고 싶다.
{
all: this.lectures,
dept: this.lectures + this.lecture.all,
기필: this.lectures + this.lecture.기필,
기선: this.lectures + this.lecture.기선,
전필: this.lectures + this.lecture.전필,
전선: this.lectures + this.lecture.전선,
심전필: this.lectures + this.lecture.심전필,
연구: this.lectures + this.lecture.연구,
}
이를 위해 다음과 같은 정규표현식 치환을 사용한다.
union\((.+), (.+)\)
$1 + $2
포맷 맞추기
승관이는 시스템 프 로그래밍을 공부하다가 공부가 하기 싫어져 모든 함수 사이 줄 간격을 일정하게 바꾸려고 한다.
기존 코드는 다음과 같다.
pid_t Fork(void);
pid_t Waitpid(pid_t pid, int *iptr, int options);
void Kill(pid_t pid, int signum);
unsigned int Sleep(unsigned int secs);
void Setpgid(pid_t pid, pid_t pgid);
void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
void Sigemptyset(sigset_t *set);
void Sigfillset(sigset_t *set);
void Sigaddset(sigset_t *set, int signum);
ssize_t Sio_puts(char s[]);
이를 다음과 같이 바꾸고 싶다.
pid_t Fork(void);
pid_t Waitpid(pid_t pid, int *iptr, int options);
void Kill(pid_t pid, int signum);
unsigned int Sleep(unsigned int secs);
void Setpgid(pid_t pid, pid_t pgid);
void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
void Sigemptyset(sigset_t *set);
void Sigfillset(sigset_t *set);
void Sigaddset(sigset_t *set, int signum);
ssize_t Sio_puts(char s[]);
이를 위해 다음과 같은 정규표현식 치환을 사용한다.
\n+
\n