简体   繁体   中英

Preg_match don't allow letters and allow 0-3 numbers for given regular expression

I want to write a preg_match function for this BNF grammar.

EXP ::= EXP + TERM | EXP - TERM | TERM

TERM ::= TERM * FACTOR | TERM / FACTOR | FACTOR

FACTOR ::= ( EXP ) | DIGIT

DIGIT ::= 0 | 1 | 2 | 3 

I don't want to allow any letters and any numbers>3 and the string should be ended with $ sign.I have tried these patterns but it doesn't work. I don't understand what mistake I making.

$pattern  = "|[0-3\+\-()*/]+\\$$|";

$pattern  = "|[^A-Za-z][0-3\+\-()*/]+\\$$|";

Edited:

Tried this also

$pattern = "|^[0-3+-()*/]+\\$$|";

but this allow 12 +1$ and I don't want to allow any number>3.

Could somebody please help me with this?

Thank you.

If you are trying to validate the expression, you're going to have to do more than just make sure only allowed characters are in there. As for the numbers? They're there because [0-3]+ matches at least one digit, but could also match dozens if it wanted.

For reference, the language your BNF describes is not regular. A pure regex would not be able to do anything with it. (It'd have to be able to keep track of how many levels of parentheses, for example...and finite-state automatons (like REs) can't count.)

Fortunately, PCREs are not just regular regexes. :) In PHP at least, they allow recursion, which is an absolute necessity in order to match nested parentheses and such.

$pattern = ':^(([0-3]|\((?1)\))([+*/-](?1))?)\$$:';

(?1) is a recursive reference, to the first subpattern -- the actual pattern, not the text it matched. It's like pasting the pattern itself in there, except you'd have a hard time cutting and pasting infinitely. :P In this case, it refers to ([0-3]|\\((?1)\\))([+*/-](?1))? .

Other than that, i'm using a simplified grammar (minus the order of operations, cause you're not going to be able to actually parse this with a regex anyway).

DIGIT  : [0-3]  
OPER   : [+*/-]
LPAREN : '('
RPAREN : ')'

EXP     : (DIGIT | LPAREN EXP RPAREN ) (OPER EXP)?
PATTERN : EXP '$'

(?1) in the actual pattern corresponds pretty much exactly to EXP.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM