简体   繁体   English

Preg_match不允许字母,并且给定正则表达式允许使用0-3个数字

[英]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. 我想为此BNF语法编写一个preg_match函数。

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. 我不想允许任何字母和任何数字> 3,并且字符串应以$符号结尾。我已经尝试了这些模式,但它不起作用。 I don't understand what mistake I making. 我不明白我犯了什么错误。

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

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

Edited: 编辑:

Tried this also 也试过了

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

but this allow 12 +1$ and I don't want to allow any number>3. 但这允许12 + 1 $,我不想允许任何数字> 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. 之所以在这里,是因为[0-3]+至少匹配一位数字,但也可以匹配几十个数字。

For reference, the language your BNF describes is not regular. 作为参考,您的BNF描述的语言不是正常的。 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.) (例如,它必须能够跟踪多少级括号,而有限状态自动机(如RE)无法计数。)

Fortunately, PCREs are not just regular regexes. 幸运的是,PCRE不仅仅是常规的正则表达式。 :) In PHP at least, they allow recursion, which is an absolute necessity in order to match nested parentheses and such. :)至少在PHP中,它们允许递归,这是匹配嵌套括号等的绝对必要条件。

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

(?1) is a recursive reference, to the first subpattern -- the actual pattern, not the text it matched. (?1)是第一个子模式的递归引用-实际模式,而不是它匹配的文本。 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))? :P在这种情况下,它指的是([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. 实际模式中的(?1)几乎完全对应于EXP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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