Help in my own gsub design

I don’t use it very often, rather copying from example, but it’s so
useful that I should learn how to write it
I’d appreciate any guru tip on how to proceed once the problem is on
the paper :

example :

INPUT STRINGS

1- input can contains spaces (should be eliminated)

2- good patterns :

2a- an Integer like 99 (no limit)
a > >= < <= <> != followed by an Integer like >99

=99 <99 <=99 <>99 !=99

2b- a String like: abcd abc99 99abc a99bc

2c- a % sign followed by a String
like %abcd %abc99 %99abc %a99bc %abcd

2d- a String followed by a % sign
like abcd% abc99% 99abc% a99bc%

2e- a String leading containing or ending with, one or many * sign(s)
like abcd a**bc99 99abc a99bc a99bc a99bc a9**9bc

3-any other pattern will be considered as wrong

OUTPUTS

2a -> an array [characters, Integer] like [ “<>”, 99]
2b, 2c, 2d,2e -> an array [ nil, String] like [nil, abcd] or [nil,
%abcd] or [nil, a99bc%] or [nil, a9**9bc]

I am interesting in understanding the design process… : how should I
start when designing such gsub routine ?
should I state it differently on paper first ? well, any tip that can
help me to build the next ones…

thanks for your support

joss

On Oct 2, 6:35 am, Josselin [email protected] wrote:

    like  %abcd  %abc99  %99abc  %a99bc %abcd

joss

def foo s
case s
when /^(>|>=|<|<=|<>|!=)?(\d+)$/
[ $1 || “”, $2.to_i ]
when /^(%)?[a-z\d]+(%)?$/
return nil if 1 != $~.captures.compact.size
[ nil, $& ]
when /^(?=.**)[*a-z\d]+$/
[ nil, $& ]
end
end

p foo( “88” )
p foo( “<>88” )
p foo( “%33” )
p foo( “33%” )
p foo( “a*9” )
p foo( ‘bat’ )

On 2007-10-02 14:46:48 +0200, William J. [email protected] said:

1- input can contains spaces (should be eliminated)
2c- a % sign followed by a String
OUTPUTS
thanks for your support
when /^(?=.**)[*a-z\d]+$/
[ nil, $& ]
end
end

p foo( “88” )
p foo( “<>88” )
p foo( “%33” )
p foo( “33%” )
p foo( “a*9” )
p foo( ‘bat’ )

thanks a lot , William, I can see how you built it… I just have 2
points to clarify if you don’t mind

1- return nil if 1 != $~.captures.compact.size
I don’t catch up

2- (?=.**)

otherwise I commented it … is my understanding correct ?

def foo s
case s
when /^(>|>=|<|<=|<>|!=)?(\d+)$/

start with > OR >= OR < OR <= OR <> OR != (0 or 1 time) then

digit(0-9) n times
[ $1 || “”, $2.to_i ]

first element or nil , second element to integer

when /^(%)?[a-z\d]+(%)?$/

start with % ( 0 or 1 time) then characters a-zA-Z 1 or n times then

end with % ( 0 or 1 time)
return nil if 1 != $~.captures.compact.size

return nil if …

  [ nil, $& ]

first element nil, second element = parameter

when /^(?=.*\*)[*a-z\d]+$/

start with *( 0 or n times)… then characters *a-zA-Z 1 or n

tiems
[ nil, $& ]

first element nil, second element = parameter

end
end

On Oct 2, 10:12 am, William J. [email protected] wrote:

This is a good point. Instead of $& (what was matched by the reg.ex.)
I should
have used the parameter of the function, s.

But s may have unwanted spaces. Stick with $&.

On Oct 2, 8:24 am, Josselin [email protected] wrote:

INPUT STRINGS
2b- a String like: abcd abc99 99abc a99bc
3-any other pattern will be considered as wrong
help me to build the next ones…
return nil if 1 != $~.captures.compact.size
p foo( “a*9” )
p foo( ‘bat’ )

thanks a lot , William, I can see how you built it… I just have 2
points to clarify if you don’t mind

1- return nil if 1 != $~.captures.compact.size
I don’t catch up

I wrote the function so that it will return nil if the string
doesn’t match your patterns. The line above is equivalent to

if 1 != $~.captures.compact.size
return nil
end

The number of succesful captures (captured by /^(%)?[a-z\d]+(%)?$/ )
must
be exactly 1; i.e., the string must begin or end with %, but not both.

2- (?=.**)

(?=…) is a zero-width look-ahead; it looks ahead but it doesn’t
move ahead in the string. I put this here to make sure that the
string contains at least one *.

otherwise I commented it … is my understanding correct ?

def foo s
case s

I forgot about spaces. If they can only be at the start or end of the
string, use
case s.strip

when /^(>|>=|<|<=|<>|!=)?(\d+)$/
    # start with > OR >= OR < OR <= OR <> OR != (0 or 1 time) then

digit(0-9) n times

1 or more times.

  [ $1 || "", $2.to_i ]
    # first element or nil , second element to integer

If 1st capture is nil, use “”; else use 1st capture.

when /^(%)?[a-z\d]+(%)?$/
    # start with % ( 0 or 1 time) then characters a-zA-Z 1 or n times then

end with % ( 0 or 1 time)
return nil if 1 != $~.captures.compact.size
# return nil if …
[ nil, $& ]
# first element nil, second element = parameter

This is a good point. Instead of $& (what was matched by the reg.ex.)
I should
have used the parameter of the function, s.