[Perl] How to check divisibility by 3 using regular expressions
Here is a Perl regular expression using Perl 5.10 extensions (this is a finite state automaton):
^(?&s)(?(DEFINE) (?<s>([0369](?&z)|[147](?&j)|[258](?&d))) (?<z>($|[0369](?&z)|[147](?&j)|[258](?&d))) (?<j>([0369](?&j)|[147](?&d)|[258](?&z))) (?<d>([0369](?&d)|[147](?&z)|[258](?&j)))) </d></j></z></s> |
States:
s – start state
z – number before modulo 3 is 0
j – number before modulo 3 is 1
d – numer before modulo 3 is 2
There is a distinction between s and z states in order to prevent expression to accept empty string as numer divisible by 3.
Here is “true” regular expression (without Perl 5.10 extensions):
^([0369]+|([258][0369]*([258][0369]*[147][0369]*)*([147]|[258][0369]*[258])|[147][0369]*([147][0369]*[258][0369]*)*([258]|[147][0369]*[147])))+$ |
Usage:
#!/usr/bin/perl for(;<>;) { if (/^([0369]+|([258][0369]*([258][0369]*[147][0369]*)*([147]|[258][0369]*[258])|[147][0369]*([147][0369]*[258][0369]*)*([258]|[147][0369]*[147])))+$/) {print ;} } |
The script will print all lines of standard input which are numbers divisible by 3.
Here is an useful link: http://perldoc.perl.org/perlretut.html