views:

654

answers:

5

Hi,

I want to parse the strings, so that to check whether they have specified syntax or not. Ex: Str = Z344-R565l t Here my requirement is after z there should be a number and after that a "-" and after that R should be there followed by a number, followed by "l", followed by a space and then finally "t".

If any thing other than this it should be a error.

I have to parse many diffirent kind of syntaxs like this. I would be ackward if write a function for each type of syntax required. I heard that yacc or lex can solve this problem.

Can any one please throw some light on my problem?

+1  A: 

You might google "runtime parser generation" or something similar...

lex and yacc (or their GNU equivaents flex and bison) do their work at compile time and may not be flexible enough for your needs. (or they may, you're not very specific).

dmckee
lex and yacc is overkill for what you want to do. They are good if you want to build a small programming language.
zooropa
+6  A: 

You do this with a regex.

Z344-R565l t

Your regex should look something like this. Not sure what regex library to use for c++, but this is the general regex to make sure that your string matches.

Z[0-9]+-R[0-9]+l t
Suroot
If all of his cases are this easy, he can indeed get away with regexps. But I always cringe from recommending them because people so often try to apply them where they don't belong.
dmckee
Agreed, I think the idea that "I can regex that" is overused. However, in instances like this I think that it would work quite well.
Suroot
+4  A: 

Use boost::regex

#include <string>
#include <boost/regex.hpp>

bool isMatch(std::string input){
    boost::regex r("Z[0-9]*-R[0-9]*l t");
    return boost::regex_search(input, r);
}

The other thing that you could do is supply a list of regex expressions in a file, one expression per line. Create a vector of boost::regex objects using the file input and iterate through the vector of patterns for each string you need to validate. It's not very efficient but it will work.

MrEvil
+4  A: 

Boost::Regex is fine if you just want to check the syntax. If you want to actually do something when you read such an expression, i suggest you use Boost::Spirit with something like :

rule<> testFormula = 
    (ch_p('Z') >> int_p) 
    >> (ch_p('-')>>ch_p('R')>>int_p>>ch_p('l')) 
    >> space_p >> ch_p('t');

I have isolated parts of the expression which you might want to connect to some action (using [] operator).

See the documentation for more information

Benoît
+1  A: 

If you have a recent compiler (VC 2008 SP1, etc.), there's no need to use boost, regex are part of TR1 and you can use them with this header: #include <regex>

Example for a date (you should use double \ as escape character):

string dateorder = "12/07/2009";

tr1::regex expr("^([1-2][0-9]|0?[1-9]|30|31)/([1-9]|10|11|12)/(2\\\d{3})$");

if (!regex_match(dateorder.begin(),dateorder.end(),expr))
{
    ...
    break; 
}
anno