C++ regex와 streamstring 사용법

C++에서 문자열을 좀더 편하게 다뤄봅니다.

regexstringstream


글을 작성하기전에

이 글에서 다루는 내용은 아주 얕습니다.

  • 저는 C++를 잘하지 못합니다.
  • PS를 위한 사용법 정도만 간단히 다루어 봅니다.
  • 나중에 자세히 알게되면 정리 포스팅을 추후 작성할 수…도 있습니다.

Regex

#include<regex>

  • C++ 11 부터 정규식이 추가 되었습니다.
  • 원리 같은것도 파악하지 않고, 파싱을 위한 아주 기초적인 사용법만 익혀봅니다.

사용법

정규식을 만들어줍니다.

reg("정규식")

1
regex reg("-?[0-9]+");
  • 해당 정규식은 숫자를 파싱하는 정규식입니다.
  • 정규식에 익숙치 않으시면 RegExr 에서 연습하시기를 적극 권장합니다.

regex용 iterator 를 만듭니다.

stregex_iterator name;

  • 일치하는 정규식을 찾지못하는 경우 end를 반환합니다.
  • 즉 찾지 못하는 경우를 처리하기 위해 const sregex_iterator end; 를 만들어 줍니다.
  • 정규식을 찾아나갈 start를 만듭니다.
  • sregex_iterator start(string.begin(), string.end(), regex);
1
2
const sregex_iterator end;
sregex_iterator start(input_str.begin(), input_str.end(), reg);

매칭되는 문자열을 찾습니다.

본래는 smatch도 설명하고 사용해야 하나, 건너뜁니다.

1
2
3
4
5
while (start != end) {
	cout << start->str() << " ";
	start++;
}
cout << "\n";

예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include<iostream>
#include<regex>
#include<sstream>
#include<string>

using namespace std;

void Get_Number_regex(string input_str){

	//regex를 이용한 정규식으로 숫자를 파싱하기
	cout << "\nregex를 이용한 정규식으로 숫자를 파싱하기\n";
	regex reg("-?[0-9]+");

	const sregex_iterator end;
	sregex_iterator start(input_str.begin(), input_str.end(), reg);
	
	while (start != end) {
		cout << start->str() << " ";
		start++;
	}
	cout << "\n";

	cout << "\nregex를 이용한 정규식으로 문자를 파싱하기\n";
	regex reg2("[A-z]+");
	sregex_iterator start2(input_str.begin(), input_str.end(), reg2);
	while (start2 != end) {
		cout << start2->str() << " ";
		start2++;
	}
	cout << "\n";
}

int main() {
	string str1 = "1A2B3CC4-5";
	
	cout << "input_str : " << str1 << "\n";
	//숫자를 추출해본다.
	Get_Number_regex(str1);

	return 0;
}

결과

1
2
3
4
5
6
7
input_str : 1A2B3CC4-5

regex를 이용한 정규식으로 숫자를 파싱하기
1 2 3 4 -5

regex를 이용한 정규식으로 문자를 파싱하기
A B CC

stringstream

#include<sstream>

  • 타입과 매칭되는것이 나올때까지 탐색합니다.
  • 중간에 매칭되는것이 없으면 종료됩니다.
  • 재사용을 위해서는 초기화 작업이 추가적으로 필요합니다.

사용법

문자열을 받을 stringstream 을 만듭니다.

stringstream name(string)

1
stringstream ss(input_str);

찾을 타입을 정하고 순회합니다.

while (ss >> num)

  • 정수, 실수, 문자열 등등 이 가능합니다.
  • cin>>이 console의 input을 stdin 에 넣는것처럼
  • stringstream을 num에 넣어줍니다.
1
2
3
int num;
while (ss >> num) cout << num << " ";
cout << "\n";

재사용을 위해서 초기화를 해줍니다.

stringstream_name.clear(), stringstream_name.str("")

  • clear를 해주어야 정상적으로 탐색합니다.
1
2
ss.clear();
ss.str(input_str);

예제 소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<regex>
#include<sstream>
#include<string>

using namespace std;

void Get_Number_streamstring(string input_str) {
	stringstream ss(input_str);
	cout << "\nstringstream를 이용한 split 구현하기\n";


	cout << "정수형 : ";
	int num;
	while (ss >> num) cout << num << " ";
	cout << "\n";
	//정수이므로 소수점은 출력하지 못한다.
	
	ss.clear();
	ss.str(input_str);

	double dd;
	cout << "실수형 : ";
	while (ss >> dd) cout << dd << " ";
	cout << "\n";


	ss.clear();
	ss.str(input_str);

	string st;
	cout << "문자열 : ";
	while (ss >> st) cout << st << " ";
	cout << "\n";
}

int main() {

	string str2 = "1 .3 5 10 11";
	Get_Number_streamstring(str2);

	return 0;
}

결과

1
2
3
4
stringstream를 이용한 split 구현하기
정수형 : 1
실수형 : 1 0.3 5 10 11
문자열 : 1 .3 5 10 11

전체소스

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#include<iostream>
#include<regex>
#include<sstream>
#include<string>

using namespace std;

void Get_Number_streamstring(string input_str) {
	stringstream ss(input_str);
	cout << "\nstringstream를 이용한 split 구현하기\n";


	cout << "정수형 : ";
	int num;
	while (ss >> num) cout << num << " ";
	cout << "\n";
	//정수이므로 소수점은 출력하지 못한다.
	
	ss.clear();
	ss.str(input_str);

	double dd;
	cout << "실수형 : ";
	while (ss >> dd) cout << dd << " ";
	cout << "\n";


	ss.clear();
	ss.str(input_str);

	string st;
	cout << "문자열 : ";
	while (ss >> st) cout << st << " ";
	cout << "\n";
}

void Get_Number_regex(string input_str){

	//regex를 이용한 정규식으로 숫자를 파싱하기
	cout << "\nregex를 이용한 정규식으로 숫자를 파싱하기\n";
	regex reg("-?[0-9]+");

	const sregex_iterator end;
	sregex_iterator start(input_str.begin(), input_str.end(), reg);
	
	while (start != end) {
		cout << start->str() << " ";
		start++;
	}
	cout << "\n";

	cout << "\nregex를 이용한 정규식으로 문자를 파싱하기\n";
	regex reg2("[A-z]+");
	sregex_iterator start2(input_str.begin(), input_str.end(), reg2);
	while (start2 != end) {
		cout << start2->str() << " ";
		start2++;
	}
	cout << "\n";
}

int main() {
	string str1 = "1A2B3CC4-5";
	
	cout << "input_str : " << str1 << "\n";
	//숫자를 추출해본다.
	Get_Number_regex(str1);
	cout << "\n====================\n";

	string str2 = "1 .3 5 10 11";
	Get_Number_streamstring(str2);


	return 0;
}

전체 결과

1
2
3
4
5
6
7
8
9
10
11
12
13
14
input_str : 1A2B3CC4-5

regex를 이용한 정규식으로 숫자를 파싱하기
1 2 3 4 -5

regex를 이용한 정규식으로 문자를 파싱하기
A B CC

====================

stringstream를 이용한 split 구현하기
정수형 : 1
실수형 : 1 0.3 5 10 11
문자열 : 1 .3 5 10 11

응용

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include<iostream>
#include<regex>
#include<sstream>
#include<string>

using namespace std;

void Get_Number_streamstring(string input_str) {
	stringstream ss(input_str);
	cout << "\nstramstring를 이용한 숫자문자를 파싱하기\n";
	//사실 문자열 하나로 전부 다 뽑을 수 있지만 연습하는 의미에서 num 따로 string 따로 나누었습니다.

	int num;
	string str;
	while (ss >> num) {
		cout << num;
		ss >> str;
		cout << str;
		cout << " / ";
	}
}

void Get_Number_regex(string input_str) {

	cout << "\nregex를 이용한 정규식으로 숫자문자를 파싱하기\n";
	regex reg("-?[0-9][A-z]+");

	const sregex_iterator end;
	sregex_iterator start(input_str.begin(), input_str.end(), reg);

	while (start != end) {
		cout << start->str() << " / ";
		start++;
	}
	cout << "\n";
}

int main() {
	string str1 = "1A 2BB 3CCC 4DDDD";

	cout << "input_str : " << str1 << "\n";


	Get_Number_regex(str1);
	cout << "\n====================\n";
	Get_Number_streamstring(str1);


	return 0;
}

응용 결과

1
2
3
4
5
6
7
8
9
input_str : 1A 2BB 3CCC 4DDDD

regex를 이용한 정규식으로 숫자문자를 파싱하기
1A / 2BB / 3CCC / 4DDDD /

====================

stramstring를 이용한 숫자문자를 파싱하기
1A / 2BB / 3CCC / 4DDDD /

Reference

  • https://word.tistory.com/24
  • https://modoocode.com/