YANQ (yet another newbie question): "string"[0.."e"]

(basi) #1

Hello,

Is there a way to say in Ruby:

"astring"[0../r/] #"ast"
"astring"[/ast/..-1] #"ring"

In other words, indexing using a "pattern".

Thanks,
basi

(Joel VanderWerf) #2

basi wrote:

Hello,

Is there a way to say in Ruby:

"astring"[0../r/] #"ast"
"astring"[/ast/..-1] #"ring"

In other words, indexing using a "pattern".

You just have to tinker with the pattern a bit:

"astring"[/.*?(?=r)/] # ==> "ast"
"astring"[/ast(.*)/, 1] # ==> "ring"

The (?=r) is a lookahead operator that matches but does not consume
characters. The numerical argument n=1 in the second example indicates
that #[] should return the value of the n-th capture

···

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

(W. James) #3

basi wrote:

Hello,

Is there a way to say in Ruby:

"astring"[0../r/] #"ast"
"astring"[/ast/..-1] #"ring"

In other words, indexing using a "pattern".

Thanks,
basi

"astring"[/.*?(?=r)/] --> "ast"
"astring"[/(.*?)r/,1] --> "ast"

"astring"[/ast(.*)/,1] --> "ring"

(basi) #4

To Joel V and William J.
I didn't think this was possible and I'm glad I asked. I'm impressed!
Thanks for the help.
basi

(Vance A Heron) #5

basi wrote:

Hello,

Is there a way to say in Ruby:

"astring"[0../r/] #"ast"
"astring"[/ast/..-1] #"ring"

In other words, indexing using a "pattern".

Thanks,
basi

I can't do it with a literal string, but think
this is close.

irb(main):004:0> irb
irb#1(main):001:0> s = 'astring'
=> "astring"
irb#1(main):002:0> s[0..s.index('r')]
=> "astr"
irb#1(main):003:0> s[s.index('ast')..-1]
=> "astring"
irb#1(main):004:0> s[s.index('rin')..-1]
=> "ring"

Note that the index for 'ast' is really 0,
so [/ast/..-1] turns into [0..-1].

HTH,
Vance

(W. James) #6

basi wrote:

Hello,

Is there a way to say in Ruby:

"astring"[0../r/] #"ast"
"astring"[/ast/..-1] #"ring"

Another approach is to remove what you don't want:

"astring".sub(/r.*/,'') --> "ast"

"astring".sub(/^ast/,'') --> "ring"

(Robert) #7

To Joel V and William J.
I didn't think this was possible and I'm glad I asked. I'm impressed!
Thanks for the help.
basi

Interestingly nobody seems to care to anchor the expression at the beginning of the string. Here are other variants that do this

"astring"[/\A[^r]*/]

=> "ast"

"astring"[/\A.*?(?=r)/]

=> "ast"

"astring".match(/\A.*?(?=r)/)[0]

=> "ast"

Kind regards

    robert

···

basi <basi_lio@hotmail.com> wrote:

(basi) #8

Wonders never cease! A very readable solution, and it stays within
basic Ruby constructs. Well within the color of my Ruby belt at this
point. I'll try it.

Though I will keep in mind the regex-based solution suggested above, as
an example of what can be done for when the pattern gets complex.

Thanks all.
basi