메타 문자는 정규 표현식 안에서 특별한 의미가 있습니다. 마침표(.)는 메타문자든 문자하나와 일치하며
여는 대괄호([)도 집합의 시작을 나타내며 메타문자입니다.
그러나. 아래와 같이 대괄호를 찾으려는 정규표현식을 찾을때 어떻게 해야할까?
예문
var myArray = new Array();
...
if(myArray[0]==0)
...
}
정규 표현식
myArray[0]
결과
var myArray = new Array();
...
if(myArray[0]==0)
...
}
즉 어떤것도 일치하지 않는다
여기서 정규표현식 myArray[0]을 잘살펴보자 대괄호는 집합을 의미하며 0은 0과 일치하는 문자를 찾으라는 뜻이다
즉 myArray0 과 일치할수밖에 없다.
그럼 대괄호를 찾으려면 어떻게 해야할까? 여는대괄호([)와 닫는대괄호(])를 이스케이프 해야한다
아래와 같이
정규표현식
myArray\[0\]
결과
var myArray = new Array();
...
if(myArray[0]==0)
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <bits/stdc++.h>
using namespace std;
void input();
string words;
int main() {
input();
cout << words << endl;
cout << "---------------------------------" << endl;
regex re(R"(myArray\[0\])");
smatch match;
while (regex_search(words, match, re)) {
cout << match[0] << endl;
words = match.suffix();
}
}
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <bits/stdc++.h>
using namespace std;
void input();
string words;
int main() {
input();
cout << words << endl;
cout << "---------------------------------" << endl;
regex re("myArray\\[0\\]");
smatch match;
while (regex_search(words, match, re)) {
cout << match[0] << endl;
words = match.suffix();
}
}
|
cs |
이번코드는 regex_search를 이용하여 찾는것을 보여줬따 sregex_iterator와 regex_search 둘다 반복해서 사용해서 익히길바랍니다.
위 2가지 코드의 차이점이 보이시나요?
하나는 regex re(R"(myArray\[0\])");와
다른 하나는 regex re("myArray\\[0\\]"); 이거다
첫번째 코드는 리터럴 상수를 사용했고
2번째 코드는 일반 문자열코드를 사용했다 차이점은 리터럴상수는 그대로 문자를 집어넣어 정규표현식을 escape했던것이고
2번째 코드는 c++내에 \를 표현하기위해 \\를 사용하여 \를 escape한다음 \를 표현하여 정규표현식에서 대괄호를 이스케이프한것이다 두가지 차이점을 잘 확인하시길 바랍니다.
만약 배열요소를 0부터 9까지 일치시키고 싶다면
정규표현식을 myArray\[[0-9]\] 로 작성할수 있습니다.
역슬래시(\) 물론 내가 글을 쓰고있는컴퓨터는 윈도우라 \는 원단위로 보이지만 역슬래시라고 생각하자역슬래시(\)는 메타문자들을 이스케이프 하는 데 사용합니다. 이말은 역슬래시(\)도 다른 메타 문자들을 이스케이프 하는데 사용합니다.
예문
\home\ben\sales\
정규표현식
\\
결과
\home\ben\sales\
여러가지 메타 문자
이전 글에서 배웠뜻이 [0-9]는 [0123456789]을 줄인표현이고 어떤 숫자와도 일치합니다.
숫자를 제외한 문자를 찾으려면[^0-9]처럼 제외하는 메타문자를 사용합니다.
그러나 더간단하게 표현하는 클래스가 있습니다.
메타 ㅁ누자 | 설명 |
\d | 숫자 하나[0-9]와 같다 |
\D | 숫자를 제외한 문자 하나[^0-9]와 같다 |
이전에 똑같은 예문을 가져오겠습니다.
예문
var myArray = new Array();
...
if(myArray[0]==0)
...
}
정규표현식
myArray\[\d\]
결과
var myArray = new Array();
...
if(myArray[0]==0)
...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <bits/stdc++.h>
using namespace std;
void input();
string words;
int main() {
input();
cout << words << endl;
cout << "---------------------------------" << endl;
regex re(R"(myArray\[\d\])");
smatch match;
while (regex_search(words, match, re)) {
cout << match[0] << endl;
words = match.suffix();
}
}
|
cs |
이런식으로 메타문자를 사용할수 있다
다른 메타문자들을 모겠따
영숫자 문자와 영숫자가 아닌 문자 찾기
메타 문자 | 설명 |
\w | 대소문자와 밑줄을 포함 모든 영숫자[a-zA-Z0-9_]와 같다 |
\W | 영숫자나 밑줄이 아닌 모든 문자[^a-zA-Z0-9_]와 같다 |
예문
11213
A1C2E3
48075
48237
M1B4F2
90046
H1H2H2
정규표현식
\w\d\w\d\w\d
결과
11213
A1C2E3
48075
48237
M1B4F2
90046
H1H2H2
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <bits/stdc++.h>
using namespace std;
void input();
string words;
int main() {
input();
cout << words << endl;
cout << "---------------------------------" << endl;
regex re(R"(\w\d\w\d\w\d)");
smatch match;
while (regex_search(words, match, re)) {
cout << match[0] << endl;
words = match.suffix();
}
}
|
cs |
공백문자와 공백이 아닌 문자 찾기
메타 문자 | 설명 |
[\b] | 역스페이스 |
\f | 페이지 넘김(form feed) |
\n | 줄바꿈 |
\r | 캐리지 리턴 |
\t | 탭 |
\v | 수직 탭 |
이번 예문에는 콤바로 구분된 (일반적으로 CSV라고 부른다) 레코드가 담겨 있다. 여러분은 데이터에 있는 빈 줄을 모두 제거 한 다음, 이 레코드를 처리해야합니다.
예문
"101","Ben","Forta"
"102","Jim","James"
"103","Roberta","Fobertson"
"104","Bob","Bobson"
정규표현식
\r\n\r\n
결과
"101","Ben","Forta"
"102","Jim","James"
"103","Roberta","Fobertson"
"104","Bob","Bobson"
\r\n은 줄바꿈과 캐리지 리턴의 조합과 일치합니다. 윈도우에서는 이조합은 줄의 끝을 나타내는데 사용합니다. 따라서 \r\n\r\n을 검색하면 줄 끝이 연속해서 두 번 나오는 부분과 일치하는데 이때 줄의 끝이 두 번 나온다는 것은 바로 두 레코드 사이에 빈 줄이 있음을 의미합니다.
메타 문자 | 설명 |
\s | 모든 공백 문자 [\f\n\r\t\v]와 같다 |
\S | 공백 문자가 아닌 모든 문자 [^\f\n\r\t\v]와 같다 |
그러나 \s나 \S에 역스페이스 메타 문자인 [\b]는 포함되지 않습니다.
포직스 문자 클래스
분류 | 내용 |
[:alnum:] | 모든 영숫자[a-zA-Z0-9]와 같다 |
[:alpha:] | 모든 영문자[a-zA-Z]와 같다 |
[:blank:] | 빈칸(space)이나 탭 문자([\t ])와 같다 |
[:cntrl:] | 아스키 제어문자(아스키 0번부터 31, 127번) |
[:digit:] | 모든 한 자리 숫자([0-9]와 같다) |
[:graph:] | [:print:]와 동일하나 빈칸(space)은 제외 |
[:lower:] | 모든 소문자([a-z]와 같다) |
[:print:] | 출력 가능한 모든 문자 |
[:punct:] | [:alnum:]이나 [:cntrl:]가 포함되지 않은 모든 문자 |
[:space:] | 빈칸을 포함한 모든 공백 문자[\f\n\r\t\v]와 같다 |
[:upper:] | 모든 대문자[A-Z]와 같다 |
[:xdigit:] | 모든 16진수 숫자[a-fA-F0-9]와 같다 |
예문
<BODY BGCOLOR="#336633" TEXT="#FFFFFF"
MARGINWIDTH="0" MARGINHEIGHT="0"
TOPMARGIN="0" LEFTMARGIN="0">
정규표현식
#[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]]
결과
<BODY BGCOLOR="#336633" TEXT="#FFFFFF"
MARGINWIDTH="0" MARGINHEIGHT="0"
TOPMARGIN="0" LEFTMARGIN="0">
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#include <bits/stdc++.h>
using namespace std;
void input();
string words;
int main() {
input();
cout << words << endl;
cout << "---------------------------------" << endl;
regex re(R"(#[[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]][[:xdigit:]])");
smatch match;
while (regex_search(words, match, re)) {
cout << match[0] << endl;
words = match.suffix();
}
}
|
cs |
앞서 사용한 패턴에서는 [0-9A-Fa-f]를 여섯번 반복했고
[0-9A-Fa-f] 는 [[:xdigit:]]를 대체하며 둘은 똑습니다.
하지만
[[:xdigit:]]를 6번이나 사용하는건 매우 비효율적입니다.
다음엔 반복을 통해서 [[:xdigit:]]를 6번 쓰는것을 어떻게 줄이는지 알아보고자 합니다
지금까지 읽어주셔서 감사합니다
궁금한점 혹은 모르는점 어떤 질문이든 댓글은 언제나 환영입니다.
공감도 눌러주실꺼죠???
'Regex' 카테고리의 다른 글
c++ regex 문자 집합(여러 문자 중 하나와 일치시키기) (0) | 2021.09.04 |
---|---|
c++ regex 모든 문자 찾기 (2) | 2021.08.31 |
c++ regex 문자 하나 찾기 (0) | 2021.08.31 |
C++ split (string 인자 여러개로 나누기, C++도 regex를 이용하여 자바나 파이썬처럼 가능합니다) (0) | 2021.08.23 |