Complex regular expression

J

jayanthigk2004

Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination


Ex


*9
*99
*999
*999-
*999-9
*999-99
*999-99-
*999-99-9
*999-99-99
*999-99-999


Or


9*
99*
999*
999-*
999-9*
999-99*
999-99-*
999-99-9*
999-99-99*
999-99-999*


Or


*9*
*99*
*999*
*999-*
*999-9*
*999-99*
*999-99-*
*999-99-9*
*999-99-99*
*999-99-999*


Any help is much appreciated.


Reply »


From: (e-mail address removed) - view profile
Date: Thurs, Oct 5 2006 6:52 pm
Email: (e-mail address removed)
Groups: microsoft.public.dotnet.languages.csharp
Not yet ratedRating:
show options
Reply | Reply to Author | Forward | Print | Individual Message | Show
original | Remove | Report Abuse | Find messages by this author


Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination


Ex


*9
*99
*999
*999-
*999-9
*999-99
*999-99-
*999-99-9
*999-99-99
*999-99-999


Or


9*
99*
999*
999-*
999-9*
999-99*
999-99-*
999-99-9*
999-99-99*
999-99-999*


Or


*9*
*99*
*999*
*999-*
*999-9*
*999-99*
*999-99-*
*999-99-9*
*999-99-99*
*999-99-999*


Any help is much appreciated.
 
J

John W. Krahn

Is it possible to write a regular expression for this ?

Pattern: 999-99-999

Where 9 is any number from 0 to 9

However the user need not enter ALL the digits and dashes as given in
the format.

Whatever numbers and dashes he had entered must match the above format,
from left to right, for only the charcters he has entered.

For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999

Any of the above should result in a match

Next, he can also put * before or after or before and after any of the
above combination


/\A\*?\d(?:\d(?:\d(?:-(?:\d(?:\d(?:-(?:\d(?:\d\d?)?)?)?)?)?)?)?)?\*?\z/



John
 
M

Mirco Wahab

Thus spoke (e-mail address removed) (on 2006-10-06 03:54):
Is it possible to write a regular expression for this ?
Pattern: 999-99-999
Where 9 is any number from 0 to 9
However the user need not enter ALL the digits and dashes as given in
the format.
Whatever numbers and dashes he had entered must match the above format,
from left to right, for only the charcters he has entered.
For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999

I'd go just straightforward and wouldn't
think of complex things here, just use
the obvious:

my $regxp=qr/(\d{1,3}[-]{0,1})
(\d{0,2}[-]{0,1})
(\d{0,3})
$/x;

and test it against the 'negative'
examples. If it won't work, one
could do another shot ;-)

Regards

Mirco
 
M

Mirco Wahab

Thus spoke Mirco Wahab (on 2006-10-06 10:25):
I'd go just straightforward and wouldn't
think of complex things here, just use
the obvious:

my $regxp=qr/(\d{1,3}[-]{0,1})
(\d{0,2}[-]{0,1})
(\d{0,3})
$/x;

Oops, I forgot the '*stars*' thing, sorry ;-)

my $regexp=qr/^
[*]{0,1}
\d{1,3}[-]{0,1}
\d{0,2}[-]{0,1}
\d{0,3}
[*]{0,1}
$/x;


Regards,

Mirco
 
M

Mirco Wahab

Thus spoke Bart Van der Donck (on 2006-10-06 10:42):
/^\*?(\d{1,3}|\d{3}-(\d{0,2}|\d{2}-\d{0,3}))\*?$/
/^\*?\d{1,3}-?\d{0,2}-?\d{0,3}\*?$/


Regards

M.
 
B

Bart Van der Donck

Mirco said:
[...]
my $regexp=qr/^
[*]{0,1}
\d{1,3}[-]{0,1}
\d{0,2}[-]{0,1}
\d{0,3}
[*]{0,1}
$/x;

No. That will incorrectly match things like

9-9
99-9999
9--
999--
99999
999999
 
M

Mirco Wahab

Thus spoke Bart Van der Donck (on 2006-10-06 10:54):
Mirco said:
my $regexp=qr/^
[*]{0,1}
\d{1,3}[-]{0,1}
\d{0,2}[-]{0,1}
\d{0,3}
[*]{0,1}
$/x;

No. That will incorrectly match things like
9-9

Yes, one would need the brackets + alternations
to fix the pattern to the left, as you said.

BTW: This looks like some
recursive regex would work ...

Any ideas?

Regards

Mirco
 
M

Mirco Wahab

Thus spoke Bart Van der Donck (on 2006-10-06 11:04):
Not correct. See my other reply to you in this thread.

Yes, you built a tree from the alternations ...

qr/^\*?
( \d{1,3}
| \d{3}- ( \d{0,2}
| \d{2}- ( \d{0,3}
)
)
)

\*?$/x;

Thanks for your beautiful and (for me) instructive
solution.

Regards

Mirco
 
C

chaitask

Hi John,

I've just read up the perldoc on perlretut and am not still very clear
on this expression.....do you think you could write up a little help
note on this (rather, on how you framed it......the process of thinking
about it and framing it)? If you have time, that is.....

Will be grateful for anything...

-Krish
 
M

Mirco Wahab

Thus spoke (e-mail address removed) (on 2006-10-06 13:21):
I've just read up the perldoc on perlretut and am not still very clear
on this expression.....do you think you could write up a little help
note on this (rather, on how you framed it......the process of thinking
about it and framing it)? If you have time, that is.....

This is just a repeated sequence of
enclosing parentheses (), which do
not save their pattern:

<`perldoc prelre`>
...
If you want to use parentheses to
delimit a subpattern (e.g., a set
of alternatives) without saving it as
a subpattern, follow the ( with a ?:
...
</`perldoc prelre`>

Regards

M.

PS. (to JW): the above don't work here, -
is there some copy/paste error?
 
I

Ian Wilson

John said:
/\A\*?\d(?:\d(?:\d(?:-(?:\d(?:\d(?:-(?:\d(?:\d\d?)?)?)?)?)?)?)?)?\*?\z/



John

As Dr Ruud pointed out in a different thread, all the solutions
involving \d will also match far more than ASCII digits 0-9. For example:
١٣-٤٢٣

Of course, this may be acceptable for the OP.
 
A

attn.steven.kuo

Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination


One way could be to construct the regular expression
based on the length of the target string itself:


my @sequence = (
'',
('\d') x 3,
'[-]',
('\d') x 2,
'[-]',
('\d') x 3
);


while (<DATA>)
{
chomp;
if (length and /^\*?(??{
no warnings 'uninitialized';
join '', @sequence[0 .. length() - pos()], '?'})\*?$/)
{
print "$_ matches\n";
}
else
{
print "$_ does NOT match\n";
}
}

__DATA__
9
*9
9*
*99-
999-
999*
z
999-99
999-990
999-99*
*999-990*
999-99-999
999-99-9999
 
J

J. Gleixner


John who?
I've just read up the perldoc on perlretut and am not still very clear
on this expression.....do you think you could write up a little help
note on this (rather, on how you framed it......the process of thinking
about it and framing it)? If you have time, that is.....

Will be grateful for anything...

OK. You owe me for fixing the order of your response.


Take a look at YAPE::Regex::Explain, which should help you understand
regular expressions.

http://search.cpan.org/~pinyan/YAPE-Regex-Explain-3.011/Explain.pm
 
D

Dr.Ruud

Ian Wilson schreef:
all the solutions
involving \d will also match far more than ASCII digits 0-9.
For example: ??-???

Of course, this may be acceptable for the OP.


I sometimes use

my $d = qr/[0-9]/

but using such a short name for such a global item is of course a bad
habit too.
(http://perl.abigail.be/Musings/coding_guidelines.html #21)


Where have all the ASCIIs gone?
Long time passing.
Where have all the ASCIIs gone?
Long time ago.
Where have all the ASCIIs gone?
They've gone to graveyards, every one.
Oh, when will they ever learn?
Oh, when will they ever learn?
http://www.fortunecity.com/tinpan/parton/2/where.html
 
B

Bart Van der Donck

Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination


One way could be to construct the regular expression
based on the length of the target string itself:


my @sequence = (
'',
('\d') x 3,
'[-]',
('\d') x 2,
'[-]',
('\d') x 3
);


while (<DATA>)
{
chomp;
if (length and /^\*?(??{
no warnings 'uninitialized';
join '', @sequence[0 .. length() - pos()], '?'})\*?$/)
{
print "$_ matches\n";
}
else
{
print "$_ does NOT match\n";
}
}

__DATA__
9
*9
9*
*99-
999-
999*
z
999-99
999-990
999-99*
*999-990*
999-99-999
999-99-9999

That still allows '**' (says: Matches) or '*' (gives error).
 
C

Charles DeRykus

Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination


Ex


*9
*99
*999
*999-
*999-9
*999-99
*999-99-
*999-99-9
*999-99-99
*999-99-999


Or


9*
99*
999*
999-*
999-9*
999-99*
999-99-*
999-99-9*
999-99-99*
999-99-999*


Or


*9*
*99*
*999*
*999-*
*999-9*
*999-99*
*999-99-*
*999-99-9*
*999-99-99*
*999-99-999*


Any help is much appreciated.


Reply »


From: (e-mail address removed) - view profile
Date: Thurs, Oct 5 2006 6:52 pm
Email: (e-mail address removed)
Groups: microsoft.public.dotnet.languages.csharp
Not yet ratedRating:
show options
Reply | Reply to Author | Forward | Print | Individual Message | Show
original | Remove | Report Abuse | Find messages by this author


Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9


However the user need not enter ALL the digits and dashes as given in
the format.


Whatever numbers and dashes he had entered must match the above format,

from left to right, for only the charcters he has entered.


For example
9
99
999
999-
999-9
999-99
999-99-
999-99-9
999-99-99
999-99-999


Any of the above should result in a match


Next, he can also put * before or after or before and after any of the
above combination

maybe I'm missing something but seems like `index' should do it once
you've eliminated the irrelevant leading/trailing *'s:

my $pat = '999-99-999';

my ( $no_star = $some_str ) =~ s/\A\*//; $no_star =~ s/\*\z//;
print "match: $some_str" if index( $pat, $no_star ) == 0;
 
A

anno4000

Charles DeRykus said:
Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9
[...]

maybe I'm missing something but seems like `index' should do it once
you've eliminated the irrelevant leading/trailing *'s:

my $pat = '999-99-999';

my ( $no_star = $some_str ) =~ s/\A\*//; $no_star =~ s/\*\z//;
print "match: $some_str" if index( $pat, $no_star ) == 0;

Not when "9 is any number from 0 to 9".

Anno
 
C

Charles DeRykus

Charles DeRykus said:
Is it possible to write a regular expression for this ?

Pattern: 999-99-999


Where 9 is any number from 0 to 9
[...]

maybe I'm missing something but seems like `index' should do it once
you've eliminated the irrelevant leading/trailing *'s:

my $pat = '999-99-999';

my ( $no_star = $some_str ) =~ s/\A\*//; $no_star =~ s/\*\z//;
print "match: $some_str" if index( $pat, $no_star ) == 0;

Not when "9 is any number from 0 to 9".

Hm,, I'm not sure why that'd invalidate this approach. If $pattern were
123-45-6789 for instance, this still works AFAICT.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,819
Latest member
masterdaster

Latest Threads

Top