[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Regexp help

Marcus Bristav

9/29/2006 9:04:00 AM

Hello everyone,

I have a string of the form

2h 3m

or

3m 2h

or

2h 3minutes

or

2hour 3min

and so on

Is there a smart regexp one liner that could produce

[2, 3]

If anyone types just for example

2

than that should produce [2]

for any of the above input? I know that there will be an m or an h.

/Marcus

15 Answers

Vincent Fourmond

9/29/2006 9:11:00 AM

0


Hello

> I have a string of the form
>
> 2h 3m
>
> or
>
> 3m 2h
> [....]
> Is there a smart regexp one liner that could produce
>
> [2, 3]

If you want to get [2,3] in both cases, that will be really difficult.
As far as I know, you can only do that in C#, which has named capturing
groups. In all the other languages I know, the capturing groups are
numbered when they are found... That rules it out.

By the way, would it be difficult to implement named capturing groups
in regular expressions ? Would that interest someone ?

Cheers !

Vince

MonkeeSage

9/29/2006 9:13:00 AM

0

Marcus Bristav wrote:
> Is there a smart regexp one liner that could produce
>
> [2, 3]

r = Regexp.new(/(\d+)h.*(\d+)m/)
s1 = "2h 3m"
s2 = "2h 3minutes"
s3 = "2hour 3min"
m = r.match(s1)
p [m[1].to_i, m[2].to_i] # => [2, 3]
m = r.match(s2)
p [m[1].to_i, m[2].to_i] # => [2, 3]
m = r.match(s3)
p [m[1].to_i, m[2].to_i] # => [2, 3]

Regards,
Jordan

Steve Callaway

9/29/2006 9:15:00 AM

0

Not so difficult, but it's not, as far as I can see, a
one liner. I am working something up at the moment
using an array of regexps.

--- Vincent Fourmond <vincent.fourmond@9online.fr>
wrote:

>
> Hello
>
> > I have a string of the form
> >
> > 2h 3m
> >
> > or
> >
> > 3m 2h
> > [....]
> > Is there a smart regexp one liner that could
> produce
> >
> > [2, 3]
>
> If you want to get [2,3] in both cases, that will
> be really difficult.
> As far as I know, you can only do that in C#, which
> has named capturing
> groups. In all the other languages I know, the
> capturing groups are
> numbered when they are found... That rules it out.
>
> By the way, would it be difficult to implement
> named capturing groups
> in regular expressions ? Would that interest someone
> ?
>
> Cheers !
>
> Vince
>
>


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail...

Steve Callaway

9/29/2006 9:24:00 AM

0

ah neat, Jordan, and more elegant than parsing an
arrayh of regexps:)

--- MonkeeSage <MonkeeSage@gmail.com> wrote:

> Marcus Bristav wrote:
> > Is there a smart regexp one liner that could
> produce
> >
> > [2, 3]
>
> r = Regexp.new(/(\d+)h.*(\d+)m/)
> s1 = "2h 3m"
> s2 = "2h 3minutes"
> s3 = "2hour 3min"
> m = r.match(s1)
> p [m[1].to_i, m[2].to_i] # => [2, 3]
> m = r.match(s2)
> p [m[1].to_i, m[2].to_i] # => [2, 3]
> m = r.match(s3)
> p [m[1].to_i, m[2].to_i] # => [2, 3]
>
> Regards,
> Jordan
>
>
>


__________________________________________________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail...

Tom Armitage

9/29/2006 9:37:00 AM

0

But, of course, that *won't* capture "3m 2h", like you described...

On 29/09/06, Steve Callaway <sjc2000_uk@yahoo.com> wrote:
> ah neat, Jordan, and more elegant than parsing an
> arrayh of regexps:)
>
> --- MonkeeSage <MonkeeSage@gmail.com> wrote:
>
> > Marcus Bristav wrote:
> > > Is there a smart regexp one liner that could
> > produce
> > >
> > > [2, 3]
> >
> > r = Regexp.new(/(\d+)h.*(\d+)m/)
> > s1 = "2h 3m"
> > s2 = "2h 3minutes"
> > s3 = "2hour 3min"
> > m = r.match(s1)
> > p [m[1].to_i, m[2].to_i] # => [2, 3]
> > m = r.match(s2)
> > p [m[1].to_i, m[2].to_i] # => [2, 3]
> > m = r.match(s3)
> > p [m[1].to_i, m[2].to_i] # => [2, 3]
> >
> > Regards,
> > Jordan
> >
> >
> >
>
>
> __________________________________________________
> Do You Yahoo!?
> Tired of spam? Yahoo! Mail has the best spam protection around
> http://mail...
>
>

MonkeeSage

9/29/2006 9:42:00 AM

0

Tom Armitage wrote:
> But, of course, that *won't* capture "3m 2h", like you described...

True...

So:

r = Regexp.new(/(\d+)h?m?.*(\d+)m?h?/)

'Course, then you'll have [3, 2] for the edge case rather than [2,
3]...but to get the full functionality that the OP described (including
the case where just "2" is given), you'd need fancier logic than just
regexp anyhow.

Regards,
Jordan

Park Heesob

9/29/2006 9:44:00 AM

0

Hi,


>From: "Marcus Bristav" <marcus.bristav@gmail.com>
>Reply-To: ruby-talk@ruby-lang.org
>To: ruby-talk@ruby-lang.org (ruby-talk ML)
>Subject: Regexp help
>Date: Fri, 29 Sep 2006 18:04:16 +0900
>
>Hello everyone,
>
>I have a string of the form
>
>2h 3m
>
>or
>
>3m 2h
>
>or
>
>2h 3minutes
>
>or
>
>2hour 3min
>
>and so on
>
>Is there a smart regexp one liner that could produce
>
>[2, 3]
>
>If anyone types just for example
>
>2
>
>than that should produce [2]
>
>for any of the above input? I know that there will be an m or an h.
>
>/Marcus
>

str = "2h 3m" # or somthing
str.scan(/(\d+)(\w*)/).sort_by{|x|x[1]}.collect{|x|x[0].to_i}

Regards,

Park Heesob



Marcus Bristav

9/29/2006 9:50:00 AM

0

On 9/29/06, Park Heesob <phasis68@hotmail.com> wrote:
>
> str = "2h 3m" # or somthing
> str.scan(/(\d+)(\w*)/).sort_by{|x|x[1]}.collect{|x|x[0].to_i}
>
> Regards,
>
> Park Heesob
>
Nice one, thanks a lot!

/Marcus

Vincent Fourmond

9/29/2006 9:55:00 AM

0


Hello again !

>> I have a string of the form
>>
>> 2h 3m
>>
>> or
>>
>> 3m 2h
>> [....]
>> Is there a smart regexp one liner that could produce
>>
>> [2, 3]
>
> If you want to get [2,3] in both cases, that will be really difficult.
> As far as I know, you can only do that in C#, which has named capturing
> groups. In all the other languages I know, the capturing groups are
> numbered when they are found... That rules it out.

Well, just to contradict myself, although this is no one-liner:

def scan(str)
re = Regexp.new(/(\d+)h.*(\d+)m|(\d+)m.*(\d+)h/)
if m = re.match(str)
return [m[1], m[2]] if m[1]
return [m[4], m[3]]
end
end

p scan("2h 3m")
p scan("3m 2h")

Cheers !

Vince

Bruno Michel

9/29/2006 10:23:00 AM

0

Vincent Fourmond a écrit :
> Hello again !
>
>>> I have a string of the form
>>>
>>> 2h 3m
>>>
>>> or
>>>
>>> 3m 2h
>>> [....]
>>> Is there a smart regexp one liner that could produce
>>>
>>> [2, 3]
>> If you want to get [2,3] in both cases, that will be really difficult.
>> As far as I know, you can only do that in C#, which has named capturing
>> groups. In all the other languages I know, the capturing groups are
>> numbered when they are found... That rules it out.
>
> Well, just to contradict myself, although this is no one-liner:
>
> def scan(str)
> re = Regexp.new(/(\d+)h.*(\d+)m|(\d+)m.*(\d+)h/)
> if m = re.match(str)
> return [m[1], m[2]] if m[1]
> return [m[4], m[3]]
> end
> end
>
> p scan("2h 3m")
> p scan("3m 2h")
>
> Cheers !
>
> Vince
>

And the one-liner :

$ irb
>> "3m
2h".scan(/(\d+)h.*(\d+)m|(\d+)m.*(\d+)h/).flatten.values_at(0,1,3,2).compact
=> ["2", "3"]
>> "2h
3m".scan(/(\d+)h.*(\d+)m|(\d+)m.*(\d+)h/).flatten.values_at(0,1,3,2).compact
=> ["2", "3"]


It's possible to add .map { |i| i.to_i } at the end of this one-liner if
the result array must contain integers instead of strings.

--
Bruno Michel