How do i convert C# Regex to C++ Regex

How would I convert the following C# Regex match pattern to use in the boost C++ regex library?

std::string m_Expression =
 "(?<={|\|)(?<KEYS>[\w]*[^=}{\|]*)=(?<VALUES>[^{][\.\w-]*[^=}{\|]*)(?=(}|\|)*)";

I am trying to parse a string out into a key value pair collection.

Thanks
johnthomaswarnerAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
Have you actually tried the regex via boost? I believe it supports most of the same features that the .NET engine supports. The only part that may fail, that I can see, is the use of unbounded quantifiers in the lookbehinds.
johnthomaswarnerAuthor Commented:
I have tried it using boost, and used the option to take it as a literal string. It returns no results from my message as opposed to using the exact same regex in .NET.

What do I need to change in the lookbehind to make it compatible with boost regex?

kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
I haven't forgotten about you. I am going to try and install the boost libraries on my Linux box and do some testing.
C++ 11 Fundamentals

This course will introduce you to C++ 11 and teach you about syntax fundamentals.

johnthomaswarnerAuthor Commented:
Once again, Thank you for your help. Here is some additional information:

Here is a sample message I am trying to parse:

1234567890{message_information={message_type=product_order|timestamp=14:09:26.20719}|order_information={order_number=281|order={customer_name=johnsmith|product=widget|price=99.99|quantity=5}}|error=0}

As you can see above, we have a message number, followed by the message, which is enclosed in brackets. It contains items that are delimited by the bar. Items can also be another nested bar-delimited
collection in brackets, and the order can be infinite.

The idea is to parse the message into a key value pair collection.
such as:
key=johnsmith value = widget
key=order_number value = 281.

The REGEX script i have above works on .NET/C#, but not in C++. I'm assuming the boost regex follows the same rules as C++.

Thanks
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
Sorry it took so long. Not having the net @ home is a real pain  :)

Firstly, you have to double-up the backslashes since they are escape characters in C++. Secondly, you have to escape the curly braces which are NOT inside of bracket-expressions (i.e. not [}{] ).

The following gave me no issues:
#include <string>
#include <iostream>
#include <boost/regex.hpp>

using namespace std;
using namespace boost;

int main()
{
        string test = "1234567890{message_information={message_type=product_order|timestamp=14:09:26.20719}|order_information={order_number=281|order={customer_name=johnsmith|p$
        regex pattern("(?<=\\{|\\|)(?<KEYS>[\\w]*[^=}{\\|]*)=(?<VALUES>[^{][\\.\\w-]*[^=}{\\|]*)(?=(\\}|\\|)*)");

        if (regex_search(test, pattern))
        {
                cout << "Matched!!\n";
        }
        else
        {
                cout << "Did not match :(\n";
        }
}

Open in new window

johnthomaswarnerAuthor Commented:
Thank you much for your help, and sorry for the delay. I noticed that the regex search does return true,
but when I try regex_match instead, it returns false. I was trying to get a key/value pair collection
from the message. Why would it do this?

Thanks.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
match tries to match the pattern to the whole string; search tries to match the pattern against a substring of the string. It's similar to Java's match and search regex methods [I don't know who came first, I just know they are similar :)  ]

If you want to ensure the whole string matches the pattern:  match.
If you want to ensure some part of the string matches the pattern:  search.
johnthomaswarnerAuthor Commented:
Gotcha. Now in my regex search, i want to return a collection of the results.
In C#, it is just simply a match collection with different groups for key/value in each match.
How would I go about this?

boost::match_results<std::string::const_iterator> m_Results;

Currently, I have just a flat collection for my results, and is only returning the first 2 keys/values, instead of all in the nested collection. What do I need to do to get a collection of keys/values i can iterate through?
key=string/value=string is fine.

Thanks



 
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
Here's an example. There could be a better/more efficient way, but I don't code in C++ (except on rare occasions such as this), so please don't hold it against me  ;)
#include <string>
#include <iostream>
#include <boost/regex.hpp>

using namespace std;
using namespace boost;

int main()
{
        string test = "1234567890{message_information={message_type=product_order|timestamp=14:09:26.20719}|order_information={order_number=281|order={customer_name=johnsmith|product=widget|price=99.99|quantity=5}}|error=0}";
        regex pattern("(?<=\\{|\\|)(?<KEYS>[\\w]*[^=}{\\|]*)=(?<VALUES>[^{][\\.\\w-]*[^=}{\\|]*)(?=(\\}|\\|)*)");
	string::const_iterator start = test.begin();
	string::const_iterator end = test.end();
	match_results<string::const_iterator> matches_obj;

	while (regex_search(start, end, matches_obj, pattern, match_default))
	{
		cout << "KEY: " << matches_obj["KEYS"] << endl << "VALUE: " << matches["VALUES"] << endl << endl;
		start = matches_obj[0].second;
	}
}

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
johnthomaswarnerAuthor Commented:
It works! Thank you so much.
kaufmed   ( ⚆ _ ⚆ )I asked the operating system what I could do to become a better programmer. It said, "Let me give you some pointers."Commented:
NP. Glad to help  :)
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Regular Expressions

From novice to tech pro — start learning today.