A Map of Regex and string

Mar 27, 2013 at 9:46am
Hi!

I want to create a map contaning a regex as key and a char* as an attribute , like:-
1
2
map<regex, char*> res;
res["[[:alnum:]]"] = "alphanumeric text";


but the following error is generated:-

no operator "[]" matches these operands
            operand types are: std::map<std::regex, char *, std::less<std::regex>, std::allocator<std::pair<const std::regex, char *>>> [ const char [5] ]


How can i create a map like the one above?

I've also tried creating a vector of a pair of regex and string, like:-
1
2
vector<pair<regex,string>>res;
res.push_back(make_pair("[[:alnum:]]","alphanumeric"));


but the error generated is:-

no instance of overloaded function "std::vector<_Ty, _Alloc>::push_back [with _Ty=std::pair<std::regex, std::string>, _Alloc=std::allocator<std::pair<std::regex, std::string>>]" matches the argument list
            argument types are: (std::pair<const char *, const char *>)
            object type is: std::vector<std::pair<std::regex, std::string>, std::allocator<std::pair<std::regex, std::string>>>


Help me on this!

Thanks! :)
Mar 27, 2013 at 10:22am
You should create regex object before adding it to the map.
Mar 27, 2013 at 10:26am
Hi and thanks for the reply...

You should create regex object before adding it to the map.

Can you please give me an example?
Mar 27, 2013 at 10:32am
http://en.cppreference.com/w/cpp/regex
1
2
3
4
std::regex reg("[[:alnum:]]");
res[reg] = "alphanumeric text";
//Or
res[std::regex("[[:alnum:]]")] = "alphanumeric text";
Mar 27, 2013 at 10:43am
That.was.EPIC!
Thanks a lot!

One more thing,
how do i iterate through it and match the regex with a string?
So far:-
1
2
3
4
5
6
7
8
9
10
11
12
13
14
map<regex, char*> table;
	
table[regex("def")] = "word_def";
table[regex("[[:alnum:]]")] = "alpha";

map<regex, char*>::iterator table_it;
string str = "def why hello()";

for (table_it = table.begin() ; table_it != table.end(); table_it++) 
	{
		int pos = str.find(table_it->first); //error here!
		if(pos != -1)
			cout << table_it->second << endl;
	}

Want go through the string and match it with the regex in the table....!
Mar 27, 2013 at 10:57am
std::string::find() cannot take regex arguments. You are probably looking for regex_search().
http://en.cppreference.com/w/cpp/regex/regex_search
Note that you can use range-based for:
1
2
for(auto x: table)
    std::cout << x.first << ' ' << x.second;
Mar 27, 2013 at 10:58am
Ok, so what I did just now is:-
1
2
3
4
5
6
7
8
9
10
11
12
13
map<regex, char*> table;
	
table[regex("def")] = "word_def";
table[regex("[[:alnum:]]")] = "alpha";

map<regex, char*>::iterator table_it;
string str = "def why hello()";

for (table_it = table.begin() ; table_it != table.end(); table_it++) 
	{
		if(std::regex_search(str,table_it->first))
			cout << table_it->second << endl;	
	}


But the compiler now gives me 17 errors (all are on the the same line and column)

error C2784: 'bool std::operator <(const std::sub_match<_BidIt> &,const 
std::sub_match<_BidIt> &)' : could not deduce template argument for 'const 
std::sub_match<_BidIt> &' from 'const std::regex'

Last edited on Mar 27, 2013 at 10:59am
Mar 27, 2013 at 11:02am
Please read example in the link I provided. regex search in C++ is womewhat complex.
Mar 27, 2013 at 11:19am
Hmmm...
Seems a bit overwhelming...
But regex_match is the one I want...
Even then, the errors are still the same (the ones above)...

1
2
3
	for(auto table_it: table)
		if(std::regex_match(str,table_it.first))
			cout << table_it.second << endl;


Seems like the Boolean operator can't understand what I'm trying to do...
Mar 27, 2013 at 11:30am
Tried to compile and realised, that regex doesnt have comparsion operator defined and types used as a key to std::map should be LessThanComparable, so you cannot use regex as key for maps.
Last edited on Mar 27, 2013 at 11:31am
Mar 27, 2013 at 12:10pm
That's is SOO annoying of C++...
Fortunately, I just found a better alternative...

Instead of using a map of a regex and a string, make vector pairs!
Like:-
1
2
3
4
5
6
7
8
9
vector<pair<regex,string>> tab;
tab.push_back(make_pair(std::regex("def"),"word_def"));
tab.push_back(make_pair(std::regex("[[:digit:]]+"),"digit"));
string str = "def why hello(12345)";
for (auto it : tab)
	{
		if(std::regex_search(str,it.first))
			cout << it.second << endl;
	}


Works JUST the way I wanted it to:-
word_def
digit


@MiiNiPaa: Thank you very VERY VERY much for your help! :)
Mar 27, 2013 at 12:15pm
map keeps its element sorted. If you don't need sorted data and access by key you should choose different container type.
This table can help you in future: http://www.liamdevine.co.uk/code/images/container.png
Mar 27, 2013 at 1:35pm
have you try unordered_map yet? It's a hash map and don't use LessThan. Not sure if regex can be hashed, though.
Mar 27, 2013 at 1:42pm
No, it's the same problem... Vector pairs solved the problem!
Topic archived. No new replies allowed.