Multiple delimiters in regex

Dec 24, 2014 at 11:12am
I want to print only the strings between the commas and semicolons, for example in str = "word1,word2;word3;"
I thought using a regex of multiple delimiters "[,;]"
But the following code does not separate word2 and word3. It treats them as one word:
word2;word3;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
    std::regex delimiter("[,;]");
    std::smatch dlm;
    std::regex_search( str, dlm, delimiter );
    std::string dlmstr = dlm.str();
    std::string str2;
    size_t pos = 0;
    int ycoor = 500;
    int xcoor;
    int xiter = 1;
    while ((pos = str.find(dlmstr)) != std::string::npos) {
        str2 = str.substr(0, pos);
        char* c2 = (char*) str2.c_str();
        textbuf->append(c2);
        xcoor = 72 + xiter*70;
        std::string psstr = ") show " + to_string(xcoor) + " " + to_string(ycoor) + " moveto (";
        char* pschar = (char*) psstr.c_str();
        textbuf->append(pschar);
        str.erase(0, pos + dlmstr.length());
        std::regex_search( str, dlm, delimiter );
        std::string dlmstr = dlm.str();
        xiter++;
    }


How to get the separate strings
word1
word2
word3
?

EDIT: complete code
Last edited on Dec 24, 2014 at 12:09pm
Dec 24, 2014 at 11:34am
In your first while loop use the ',' delimiter.
then inside your while loop call the same function with ';' delimiter.
Dec 24, 2014 at 11:39am
Line 10: It creates a variable which is instantly destroyed because it is going out of scope.

Post complete code illustrating a problem.
Dec 24, 2014 at 12:30pm
if your format will be the same sequence all the time you can try the code below.

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
#include <iostream>
#include <vector>
#include <string>

using namespace std;

int main()
{
	string line = "10,11;12";
	string delimiter = ",";
	string delimiter2 = ";";
	
	string token;
	string token2;
	
	size_t pos = 0;
	size_t pos_2 = 0;

	while ((pos = line.find(delimiter)) != std::string::npos) 
	{
		// extract the first value
		token = line.substr(0, pos);
		
		line.erase(0, pos + delimiter.length());

		// output 10
		std::cout << token << std::endl;
	}	

	while ((pos_2 = line.find(delimiter2)) != std::string::npos) 
	{
		token2 = line.substr(0,pos_2);
		
		line.erase(0, pos_2 + delimiter2.length());
			
		// output 11
		std::cout << token2 << std::endl;
	}


	// output 12
	std::cout << line << std::endl;

	int x;
	cin >> x;
}
Dec 24, 2014 at 12:39pm
@rafae11

No, the same string can also be: str = "word1,word2;word1,"
So the delimiter has to be either ',' or ';'
In my program, once a delimiter is chosen, it stays the same in each iteration of the while loop. But I want it to check whether the other delimiter occurs in the updated string after erase.
Please adhere to my code and tell me what the problem is.
Dec 24, 2014 at 12:48pm
Code is still not complete. It should:
a) compile
b) actually show an error: say, output separated strings to show that some of them are not separated properly
c) Should not have any code which is not related to the problem.

This is what minimal code illustrating problem is.
Dec 24, 2014 at 12:58pm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
std::string str ("10,11;12,13;");
	std::regex delimiter("[;,]");
    std::smatch dlm;
    
	while(std::regex_search( str, dlm, delimiter ))
	{
		for (auto x:dlm) 
		{
			std::size_t pos = str.find(x); 
			std::cout << str.substr(0,pos);			
		}
		
		std::cout << std::endl;
		str = dlm.suffix().str();
	}
   
Dec 24, 2014 at 1:01pm
Why actually use regex on this task? Isn't it an overkill?
Good old string search functions will do trick for you:
1
2
3
4
5
6
7
8
9
10
11
int main()
{
    std::string str = "word1,word2;word3";
    std::string::size_type pos = std::string::npos;
    while ((pos = str.find_first_of(",;")) != std::string::npos) {
        std::string str2 = str.substr(0, pos);
        std::cout << str2 << endl;
        str.erase(0, pos + 1);
    }
    std::cout << str; // last word
}
If you want more flexibility, custom facets will help greatly too.
Topic archived. No new replies allowed.