Regexp: named captures

How do named captures in Ruby work? This is what I've tried:

irb(main):001:0> if /(?<name>.+)/ =~ /ari/
irb(main):002:1> puts $name
irb(main):003:1> end
SyntaxError: compile error
(irb):1: undefined (?...) sequence: /(?<name>.+)/
         from (irb):3

and if I do this:

irb(main):007:0> if /(<name>.+)/ =~ /ari/
irb(main):008:1> puts $name
irb(main):009:1> end
TypeError: can't convert Regexp into String
         from (irb):7

I get a Regexp => String error.

Bwah?
aRi
-------------------------------------------|
Nietzsche is my copilot

Ruby doesn't have named-captures.

Coming from .NET myself, at first I was dissapointed. Eventually I
grew to love the simplicity of $1, $2, etc, but that's just me. :slight_smile:

Ari Brown pisze:

How do named captures in Ruby work? This is what I've tried:

irb(main):001:0> if /(?<name>.+)/ =~ /ari/
irb(main):002:1> puts $name
irb(main):003:1> end

1.9 supports that (so will 2.0):

if match = /(?<name>blah)/.match("blah")
     puts match["name"]
end

lopex

A work-around:

md = "foo bar".match( /(\w+) (\w+)/ )
    ==>#<MatchData:0x2851ef0>
name, surname = md.captures
    ==>["foo", "bar"]
name
    ==>"foo"
surname
    ==>"bar"

···

On Aug 20, 2:44 pm, Ari Brown <a...@aribrown.com> wrote:

How do named captures in Ruby work? This is what I've tried:

irb(main):001:0> if /(?<name>.+)/ =~ /ari/
irb(main):002:1> puts $name
irb(main):003:1> end
SyntaxError: compile error
(irb):1: undefined (?...) sequence: /(?<name>.+)/
         from (irb):3

and if I do this:

irb(main):007:0> if /(<name>.+)/ =~ /ari/
irb(main):008:1> puts $name
irb(main):009:1> end
TypeError: can't convert Regexp into String
         from (irb):7

I get a Regexp => String error.

Bwah?
aRi
-------------------------------------------|
Nietzsche is my copilot

Hi --

···

On Tue, 21 Aug 2007, Sam Smoot wrote:

Ruby doesn't have named-captures.

The new regex engine, Oniguruma, does. You can install it in 1.8, and
it's included in 1.9/2.0.

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

Or my favorite (courtesy of Ara):

_, name, surname = /(\w+) (\w+)/.match("foo bar").to_a

···

On Aug 20, 3:32 pm, William James <w_a_x_...@yahoo.com> wrote:

On Aug 20, 2:44 pm, Ari Brown <a...@aribrown.com> wrote:
> How do named captures in Ruby work? This is what I've tried:

A work-around:

md = "foo bar".match( /(\w+) (\w+)/ )
    ==>#<MatchData:0x2851ef0>
name, surname = md.captures
    ==>["foo", "bar"]
name
    ==>"foo"
surname
    ==>"bar"

I really enjoyed the article. It proved to be Very helpful to me and I

am sure to all the comment here!

···

--
Posted via http://www.ruby-forum.com/.

I've read about Oniguruma - is it just a different engine behind class Regex, and it won't change the syntax, right?

Because there's a Regexp wrapper I'm writing (with much help from Robert Klemme) that uses Regex as the base, and all of the current syntax.

~ Ari
English is like a pseudo-random number generator - there are a bajillion rules to it, but nobody cares.

···

On Aug 20, 2007, at 4:13 PM, David A. Black wrote:

On Tue, 21 Aug 2007, Sam Smoot wrote:

Ruby doesn't have named-captures.

The new regex engine, Oniguruma, does. You can install it in 1.8, and
it's included in 1.9/2.0.

name, surname = /(\w+) (\w+)/.match("foo bar").captures

···

On Aug 20, 4:40 pm, Phrogz <phr...@mac.com> wrote:

On Aug 20, 3:32 pm, William James <w_a_x_...@yahoo.com> wrote:

> On Aug 20, 2:44 pm, Ari Brown <a...@aribrown.com> wrote:
> > How do named captures in Ruby work? This is what I've tried:
> A work-around:

> md = "foo bar".match( /(\w+) (\w+)/ )
> ==>#<MatchData:0x2851ef0>
> name, surname = md.captures
> ==>["foo", "bar"]
> name
> ==>"foo"
> surname
> ==>"bar"

Or my favorite (courtesy of Ara):

_, name, surname = /(\w+) (\w+)/.match("foo bar").to_a

What do you mean by "change the syntax"?

For example, Oniguruma supports named captures (per this thread) and
zero-width negative lookbehind assertions, and ... more.

Certainly the syntax is different for new features, which cause the
current regexp engine to barf. Do you mean syntax inside the regex? Or
the syntax for declaring a regex? Or are you interested only in
backwards compatibility?

···

On Aug 20, 4:00 pm, Ari Brown <a...@aribrown.com> wrote:

I've read about Oniguruma - is it just a different engine behind
class Regex, and it won't change the syntax, right?

Because there's a Regexp wrapper I'm writing (with much help from
Robert Klemme) that uses Regex as the base, and all of the current
syntax.

Hi --

···

On Tue, 21 Aug 2007, William James wrote:

On Aug 20, 4:40 pm, Phrogz <phr...@mac.com> wrote:

On Aug 20, 3:32 pm, William James <w_a_x_...@yahoo.com> wrote:

On Aug 20, 2:44 pm, Ari Brown <a...@aribrown.com> wrote:

How do named captures in Ruby work? This is what I've tried:

A work-around:

md = "foo bar".match( /(\w+) (\w+)/ )
    ==>#<MatchData:0x2851ef0>
name, surname = md.captures
    ==>["foo", "bar"]
name
    ==>"foo"
surname
    ==>"bar"

Or my favorite (courtesy of Ara):

_, name, surname = /(\w+) (\w+)/.match("foo bar").to_a

name, surname = /(\w+) (\w+)/.match("foo bar").captures

That has the disadvantage that it will blow up if the match fails (no
captures method for nil).

David

--
* Books:
   RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242\)
   RUBY FOR RAILS (http://www.manning.com/black\)
* Ruby/Rails training
     & consulting: Ruby Power and Light, LLC (http://www.rubypal.com)

What do you mean by "change the syntax"?

I mean change the basic regexp syntax.

For example, Oniguruma supports named captures (per this thread) and
zero-width negative lookbehind assertions, and ... more.

Certainly the syntax is different for new features, which cause the
current regexp engine to barf. Do you mean syntax inside the regex? Or
the syntax for declaring a regex? Or are you interested only in
backwards compatibility?

So yea, just backwards compatibility.

Is Oniguruma behind a new class Oniguruma.new or behind Regexp.new

Sorry, but I can't seem to find much documentation on it.

Ari
-------------------------------------------|
Nietzsche is my copilot

···

On Aug 20, 2007, at 6:10 PM, Phrogz wrote:

# Hi,

# I need some help in simplefying my life
# I need to create lots of tables from arrays and I need to provide
# each of the columns with a heading. For eample, I have
# two headings "a-value" and "b-value" specified as follows:
a = ["a-value", "b-value"]
b = [10, 10]
# The array b contains the width of the field, so that I get:
# a-value b-value
# Two ways to do this are as follows:
puts "#{'a-value'.rjust(10)}#{'b-value'.rjust(10)}"
puts "#{a[0].rjust(b[0])}#{a[1].rjust(b[1])}"

# which is difficult to debug, so that I'm looking for
# a simpler process, specificaly by writing a function.
# The following one works:

def heading2(x, n)
   x.length.times do |i|
     print "#{x[i].rjust(n[i])}"
   end
   print "\n\n"
end

puts
heading2(a,b)

# But this approach doesn't. Why not? Are there other ways to make this simpler?

def heading1(x, n)
   s = ""
   x.length.times do |i|
     s = s + "\#{\'" + x[i] + "\'.rjust(" + n[i].to_s + ")}"
   end
   p s
   print s
   puts s
   return s
end

heading1(a,b)
puts "#{heading1(a, b)}"
puts "\"#{heading1(a, b)}\""

# Thanks ahead. (NOTE: This file can be run from TextMate)

Peter Versteegen
pversteegen@gcnetmail.net

I believe that under 1.8 it comes as its own class, but in 1.9 on it
is the code behind the builtin Regexp class. (I could be wrong,
though. There may be a way to build 1.8 using Oniguruma as the basis
for Regexp.)

And, from what I know, all regex features available in 1.8 use the
same syntax in Oniguruma.

···

On Aug 20, 5:17 pm, Ari Brown <a...@aribrown.com> wrote:

On Aug 20, 2007, at 6:10 PM, Phrogz wrote:

> What do you mean by "change the syntax"?

I mean change the basic regexp syntax.

> For example, Oniguruma supports named captures (per this thread) and
> zero-width negative lookbehind assertions, and ... more.

> Certainly the syntax is different for new features, which cause the
> current regexp engine to barf. Do you mean syntax inside the regex? Or
> the syntax for declaring a regex? Or are you interested only in
> backwards compatibility?

So yea, just backwards compatibility.

Is Oniguruma behind a new class Oniguruma.new or behind Regexp.new

Sorry, but I can't seem to find much documentation on it.

How about using "rescue nil" ?

ruby -e 'name, surname = /(\w+) (\w+)/.match("foo bar").captures rescue
nil; p name, surname'
=> "foo"
=> "bar"

ruby -e 'name, surname = /(\w+) (\w+)/.match("").captures rescue nil; p
name, surname'
=> nil
=> nil

Cheers,

j.k.

···

--
Posted via http://www.ruby-forum.com/.

Hi Peter.

···

On 22 Aug 2007, at 12:21, Peter Versteegen wrote:

# But this approach doesn't. Why not? Are there other ways to make this simpler?

Maybe I've got the wrong end of the stick on this, but I get it to work like this:

==========================

a = ["a-value","b-value", "c-value"]
b = [10,30,15]

def header(names, widths)
   header = ''
   names.each_with_index do |v,i|
     header += v.rjust widths[i]
   end
   header
end

p header(a, b)

==========================

Hope this helps.

Douglas F Shearer
dougal.s@gmail.com

Ruby Reports. Ruport. Check it out.

···

On Aug 22, 2007, at 7:21 AM, Peter Versteegen wrote:

# Hi,

# I need some help in simplefying my life
# I need to create lots of tables from arrays and I need to provide
# each of the columns with a heading. For eample, I have
# two headings "a-value" and "b-value" specified as follows:
a = ["a-value", "b-value"]
b = [10, 10]
# The array b contains the width of the field, so that I get:
# a-value b-value
# Two ways to do this are as follows:
puts "#{'a-value'.rjust(10)}#{'b-value'.rjust(10)}"
puts "#{a[0].rjust(b[0])}#{a[1].rjust(b[1])}"

# which is difficult to debug, so that I'm looking for
# a simpler process, specificaly by writing a function.
# The following one works:

def heading2(x, n)
  x.length.times do |i|
    print "#{x[i].rjust(n[i])}"
  end
  print "\n\n"
end

puts
heading2(a,b)

# But this approach doesn't. Why not? Are there other ways to make this simpler?

def heading1(x, n)
  s = ""
  x.length.times do |i|
    s = s + "\#{\'" + x[i] + "\'.rjust(" + n[i].to_s + ")}"
  end
  p s
  print s
  puts s
  return s
end

heading1(a,b)
puts "#{heading1(a, b)}"
puts "\"#{heading1(a, b)}\""

# Thanks ahead. (NOTE: This file can be run from TextMate)

Peter Versteegen
pversteegen@gcnetmail.net

---------------------------------------------------------------|
~Ari
"I don't suffer from insanity. I enjoy every minute of it" --1337est man alive

Peter Versteegen wrote:

# But this approach doesn't. Why not? Are there other ways to make
this simpler?

Here's an idea that's simpler ... if you already have all the tools in place.

Push your raw data into XML. Write an XSLT that converts it to XHTML.
Pipe this thru `lynx -dump`.

No joke: I have done that to produce beautiful automated text-only
e-mails, containing tables of data.

···

--
Phlip
Test Driven Ajax (on Rails) [Book]
^ assert_xpath
O'Reilly Media - Technology and Business Training <-- assert_latest Model

Douglas,

Thanks, this works also. The result is put in a string and the string is printed.

I guess what I was trying to do is to create a string that ruby is supposed to interpret, or execute. Perhaps there is another command to accomplish this.

Peter

···

On Aug 22, 2007, at 8:07 AM, Douglas F Shearer wrote:

Hi Peter.

On 22 Aug 2007, at 12:21, Peter Versteegen wrote:

# But this approach doesn't. Why not? Are there other ways to make this simpler?

Maybe I've got the wrong end of the stick on this, but I get it to work like this:

==========================

a = ["a-value","b-value", "c-value"]
b = [10,30,15]

def header(names, widths)
  header = ''
  names.each_with_index do |v,i|
    header += v.rjust widths[i]
  end
  header
end

p header(a, b)

==========================

Hope this helps.

Douglas F Shearer
dougal.s@gmail.com
http://douglasfshearer.com

Ari,

Had not come across Ruport. Sounds interesting, especially since I have to do a lot of reporting. I will investigate further.

Thanks,

Peter

···

On Aug 22, 2007, at 3:10 PM, Ari Brown wrote:

Ruby Reports. Ruport. Check it out.

On Aug 22, 2007, at 7:21 AM, Peter Versteegen wrote:

# Hi,

# I need some help in simplefying my life
# I need to create lots of tables from arrays and I need to provide
# each of the columns with a heading. For eample, I have
# two headings "a-value" and "b-value" specified as follows:
a = ["a-value", "b-value"]
b = [10, 10]
# The array b contains the width of the field, so that I get:
# a-value b-value
# Two ways to do this are as follows:
puts "#{'a-value'.rjust(10)}#{'b-value'.rjust(10)}"
puts "#{a[0].rjust(b[0])}#{a[1].rjust(b[1])}"

# which is difficult to debug, so that I'm looking for
# a simpler process, specificaly by writing a function.
# The following one works:

def heading2(x, n)
  x.length.times do |i|
    print "#{x[i].rjust(n[i])}"
  end
  print "\n\n"
end

puts
heading2(a,b)

# But this approach doesn't. Why not? Are there other ways to make this simpler?

def heading1(x, n)
  s = ""
  x.length.times do |i|
    s = s + "\#{\'" + x[i] + "\'.rjust(" + n[i].to_s + ")}"
  end
  p s
  print s
  puts s
  return s
end

heading1(a,b)
puts "#{heading1(a, b)}"
puts "\"#{heading1(a, b)}\""

# Thanks ahead. (NOTE: This file can be run from TextMate)

Peter Versteegen
pversteegen@gcnetmail.net

---------------------------------------------------------------|
~Ari
"I don't suffer from insanity. I enjoy every minute of it" --1337est man alive