Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

regexp

Status
Not open for further replies.

fl0ra

MIS
Jul 27, 2004
93
0
0
FR
Hello guys,
trying to compute the regexp for this problem, but I can't get it right.
Here is the string
the string is only composed of at maximum one of each of the following letter A, F, P, and G.
and it can include all the them (so max size is 4)
so a valid result could be

A
AG
APG
AGF
GFAP

but not
FAGF
nor obviously
AFGZ


I came up with
regexp -- {[A|F|G|P]{1,4}} $string
but it is obviously way too simple and does not work in all case.
Anyone has an idea???

 
You were almost there...

regexp {^([A|F|G|P]+){1,4}$} $string

 
Thank you so much
I am gonna test it, but it seems like it is gonna work :)
 
Hi

Yes, but that expression will not catch the duplicated letters like in "FAGF". In facts, I think that can not be catched easily with regular expression. Use this additionally to cptk's suggestion :
Code:
[[b]expr[/b] [[b]string[/b] length [[b]regsub[/b] -all {(.)\1} [[b]join[/b] [[b]lsort[/b] [[b]split[/b] $string ""]] ""] {\1}]]==[[b]string[/b] length $string]]
Ugly.

Feherke.
 
Yeah, after I submitted the response I realized the suggestion didn't quite fit the bill (i.e. - duplicate approved letters)...

Is the requirement still stand such that it has to be in a "regexp" ? [I'm thinking of the forward-looking funtionality in regexp's, but it's been a while]

If not, the best I can quickly think of is using a routine, as follows:


set SS "ABCB" ;## your $string var

if {[regexp {^([A|B|C|D]){1,4}$} $SS]} {

foreach i {A B C D} {
if {[string first $i $SS] != [string last $i $SS]} {
puts "Dup $i's"
}
}
} else {
puts "Bad Data"
}


And note that that you should remove the "+" in my original post ( regexp {^([A|F|G|P]){1,4}$} $string )

 
Hi

Nice solution, cptk. Just a single thing : no need for pipe ( | ) inside the character set, neighter for parenthesis ( () ) around the set :
Code:
if {[regexp {^[ABCD]{1,4}$} $SS]} {
  ...
All that are needed if you write the expression this way, without character set :
Code:
if {[regexp {^(A|B|C|D){1,4}$} $SS]} {
  ...
Which is slower to execute.

Feherke.
 
thank you so much guys.
No there is no need to use regexp. I just thought it would be nicer instead of using a foreach.
I guess there is not many other solutions, or is there?
 
feherke,
I agree, there's absolutely no need for the "|"'s nor "()"'s - I was trying to quickly test forward-looking functionality within regexp's using both the "()"'s and "\1", but abandon it - it was proven to be a little messy and wasn't quite working like I wanted it to.

so fl0ra, there are a various solutions via some kind of looping mechanism, but not within a nice single regexp cmd (that I could find or think of).

 
Hi

Of course ! You are right cptk, good idea that [tt]\1[/tt].
Code:
regexp {([ABCD]).*\1} $SS
So combined with the cptk's first expression using and ( [tt]&&[/tt] ) and negation ( [tt]![/tt] ), will give those desired words :
Code:
if {[regexp {^[ABCD]{1,4}$} $SS] && ![regexp {([ABCD]).*\1} $SS]} {
  ...

Feherke.
 
feherke -

I was trying to utilize the "\1" (plus "\2", etc.) in one regexp ... couldn't get it to work ...

I like your last idea the best ... nice job!!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top