Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

RFC: Perl regex to validate arithmetic expressions

by Serge314 (Acolyte)
on Feb 21, 2011 at 15:46 UTC ( [id://889408]=perlmeditation: print w/replies, xml ) Need Help??

Sorry, I'm not a native English speaker. Professional Perl programmers doubt that with one regex can validate arithmetic expressions, because of unlimited level of nested parentheses, and they use special Perl modules for this purpose. I wrote such regex. To do this, I used simple and elegant method by which you can write a similar complex expressions. I wrote an article about it, but unfortunately not in English ...
Here's my example:

#!perl -w use strict; use re 'eval'; # Validation of arithmetic expressions like +1*(2-3/(4*5)) # Author: Serge Melnikov (www.cronc.com) my @testexpr=( # Valid arithmetic expressions: '+3', '-(3/4+(-2-3)/3)', '(-((3)))', '-(+1+2)*(3/(1-2))/((-3))', # Invalid (from the point of view of a human or mathematical notation) + arithmetic expressions: '2*-3', # in math we must write 2*(-3) '-(3/4+(-2-3)/3', '(-((3)+))'); my $number=qr/\d+/; # the regex for a term (number/variable/function c +all) my $arithm; # The x modifier used only to split the long regex to publish it $arithm=qr#[+-]?(?:$number|\((??{$arithm})\))(?:[*/](?:$number|\((??{$ +arithm})\)))* (?:[+-](?:$number|\((??{$arithm})\))(?:[*/](?:$number|\((??{$arithm +})\)))*)*#x; print /^$arithm$/ ? "Valid: $_\n" : "Invalid: $_\n" for (@testexpr);

Replies are listed 'Best First'.
Re: RFC: Perl regex to validate arithmetic expressions
by JavaFan (Canon) on Feb 21, 2011 at 23:14 UTC
    my $pat = qr { (?(DEFINE) (?<number> (?: [0-9]+ )) (?<sign> (?: [-+] )) (?<expr> (?: (?&term) (?: \s* [-+] \s* (?&expr))? )) (?<term> (?: (?&factor) (?: \s* [/*] \s* (?&term))? )) (?<factor> (?: (?&number) | (?&sign) \s* (?&factor) | \( \s* (?&expr) \s* \))) ) (?&expr) }x;
    That will even parse 2*-3, and doesn't require (??{ }), or use re 'eval';.
Re: RFC: Perl regex to validate arithmetic expressions
by Fox (Pilgrim) on Feb 21, 2011 at 16:57 UTC
    That's pretty cool, I didn't knew about the re 'eval' and this just opened my mind to a whole new class of solutions using these 'recursive' regexes.

    I just don't like the lack of whitespace, maybe you could allow it by adding a s/\s//g before the main test ? not sure if it will break the test.
Re: RFC: Perl regex to validate arithmetic expressions
by mellon85 (Monk) on Feb 21, 2011 at 18:53 UTC
    You actually can parse an arithmetic expression with a "regular" expression if it uses a stack automata. Just think that a regular language can't even check if there is a correct number of parenthesis if the maximum depth is undefined, as such, strictly speaking that is not so much regular...
      Since 5.10, Perl regular expressions can match anything that's matched by a context-free grammar - and then some (backreferences add even more power). Matching balanced parenthesis is easy in 5.10 and later: /^(\((?1)*\))$/.
Re: RFC: Perl regex to validate arithmetic expressions
by spx2 (Deacon) on Mar 15, 2011 at 16:43 UTC
    there's also the option of using Parse::Yapp and validating arithmetic expressions. In general when "discovering" Perl regexes you think they are so powerful that you can use them for a lot of stuff, but if all you have is a hammer, everything looks like a nail.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://889408]
Front-paged by Anonyrnous Monk
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (3)
As of 2024-04-24 22:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found