Regular expression gurus--help!

I want all possible three letter sets for a string. Scan does this:

"abcdefghijkl".scan(...)

# >> abc
# >> def
# >> ghi
# >> jkl

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression--basically need to force the index
to advance one position rather than to the end of a match before
starting the next attempt.
Thanks in advance,
Tim

Here is one way to get that result.
(But not with a regular expression)
Not all 3 letter sets but I think this is the result you are really looking for.

str = "abcdefghijkl"
puts str.unpack("a3X2"*(str.length-2))

#output
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jkl

Harry

···

On Sun, Jun 21, 2009 at 4:10 PM, timr<timrandg@gmail.com> wrote:

I want all possible three letter sets for a string. Scan does this:
>

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression

--
A Look into Japanese Ruby List in English

=> ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]

HTH,
Sebastian

···

Am Sonntag 21 Juni 2009 09:10:37 schrieb timr:

I want all possible three letter sets for a string. Scan does this:
>

>>"abcdefghijkl".scan(...)

# >> abc
# >> def
# >> ghi
# >> jkl

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

"abcdefghijkl".scan(/(.)(?=(..))/).map(&:join)

I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression--basically need to force the index
to advance one position rather than to the end of a match before
starting the next attempt.
Thanks in advance,
Tim

And another way. :slight_smile:
Again without a regular expression.

str = "abcdefghijkl"
(0..str.length-3).each {|x| p str[x..x+2]}

Harry

···

--
A Look into Japanese Ruby List in English

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

Ruby has so many ways. :slight_smile:

str, arr = "abcdefghijkl",
3.times {|f| arr << str[f..f-3].split(//)}
p arr.transpose.map{|u| u.join}

Harry

···

--
A Look into Japanese Ruby List in English

I fail to understand what do you mean by "all possible three-letter sets",
but it seems there is a method called 'each_cons' that does something in the
lines of your discussion. You might find it helpful:
http://corelib.rubyonrails.org/classes/Enumerable.html#M002196

···

On Sun, Jun 21, 2009 at 11:08 AM, Harry Kakueki <list.push@gmail.com> wrote:

On Sun, Jun 21, 2009 at 4:10 PM, timr<timrandg@gmail.com> wrote:
> I want all possible three letter sets for a string. Scan does this:
> >
>
> But I need:
> # >> abc
> # >> bcd
> # >> cde
> # >> def
> etc.
>
> I used to know the secret spell, but forgot it. Does anyone know how
> to do this with regular expression
>

Here is one way to get that result.
(But not with a regular expression)
Not all 3 letter sets but I think this is the result you are really looking
for.

str = "abcdefghijkl"
puts str.unpack("a3X2"*(str.length-2))

#output
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jkl

Harry

--
A Look into Japanese Ruby List in English
http://www.kakueki.com/ruby/list.html

require'enumerator'
"qwertyuiopasdfgd".scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}
"qwe"
"wer"
"ert"
"rty"
"tyu"
"yui"
"uio"
"iop"
"opa"
"pas"
"asd"
"sdf"
"dfg"
"fgd"

···

On Jun 21, 4:08 pm, Harry Kakueki <list.p...@gmail.com> wrote:

On Sun, Jun 21, 2009 at 4:10 PM, timr<timra...@gmail.com> wrote:
> I want all possible three letter sets for a string. Scan does this:
> >

> But I need:
> # >> abc
> # >> bcd
> # >> cde
> # >> def
> etc.

> I used to know the secret spell, but forgot it. Does anyone know how
> to do this with regular expression

Here is one way to get that result.
(But not with a regular expression)
Not all 3 letter sets but I think this is the result you are really looking for.

str = "abcdefghijkl"
puts str.unpack("a3X2"*(str.length-2))

#output
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jkl

Harry

--
A Look into Japanese Ruby List in Englishhttp://www.kakueki.com/ruby/list.html

I am not the OP, but thanks for that solution.
I learned more about regular expressions and relearned something about scan.

It did not work on my machine so I changed it to this.
p "abcdefghijkl".scan(/(.)(?=(..))/).map{|x| x.join}

Is this map(&:join) using 1.9?

Harry

···

On Sun, Jun 21, 2009 at 9:26 PM, Sebastian Hungerecker<sepp2k@googlemail.com> wrote:

Am Sonntag 21 Juni 2009 09:10:37 schrieb timr:

I want all possible three letter sets for a string. Scan does this:
>

>>"abcdefghijkl".scan(...)

# >> abc
# >> def
# >> ghi
# >> jkl

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

"abcdefghijkl".scan(/(.)(?=(..))/).map(&:join)

=> ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]

HTH,
Sebastian

--
A Look into Japanese Ruby List in English

In message "Re: regular expression gurus--help!"

  >>> "abcdefghijkl".scan(/(.)(?=(..))/).map(&:join)
  > => ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]

I find this really interesting, but what version of Ruby is this? I am
not able to reproduce your result.

$ ruby -v
ruby 1.8.7 (2008-08-11 patchlevel 72) [i486-linux]
$ ruby1.9 -e 'p "abcdefghijkl".scan(/(.)((?=..))/).map(&:join)'
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]

$ ruby1.9 -v
ruby 1.9.0 (2008-06-20 revision 17482) [i486-linux]
$ ruby1.9 -e 'p "abcdefghijkl".scan(/(.)((?=..))/).map(&:join)'
["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]

Or is this a feature of 1.9.1?

···

on 09/06/21, Sebastian Hungerecker <sepp2k@googlemail.com> wrote:

--
/*** Hewlett-Packard Japan, Ltd. ***/
/*** EDS Application Services ***/
/*** Consumer Industries & Retail, Department #4 ***/
/*** Nakagawa, Makoto(中川 誠) 050 3158 4747 (Dial-In) ***/
/*** PGP: 0B33 EAC3 F2F6 3D10 D9E9 AE7F 8EDA 44F9 1D29 D44A ***/

Or even

"qwertyuiopasdfgd".
   scan(/./).
   each_cons(3) {|a| p a.join}

Kind regards

  robert

···

On 21.06.2009 10:59, Hooopo wrote:

require'enumerator'
"qwertyuiopasdfgd".scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Hi --

I want all possible three letter sets for a string. Scan does this:
>

But I need:
# >> abc
# >> bcd
# >> cde
# >> def
etc.

I used to know the secret spell, but forgot it. Does anyone know how
to do this with regular expression

Here is one way to get that result.
(But not with a regular expression)
Not all 3 letter sets but I think this is the result you are really looking for.

str = "abcdefghijkl"
puts str.unpack("a3X2"*(str.length-2))

#output
abc
bcd
cde
def
efg
fgh
ghi
hij
ijk
jkl

Harry

--
A Look into Japanese Ruby List in Englishhttp://www.kakueki.com/ruby/list.html

require'enumerator'
"qwertyuiopasdfgd".scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}

Here's another variant on this one, for 1.9:

str = "abcdefghij"

=> "abcdefghij"

str.chars.each_cons(3).map {|c| c.join }

=> ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij"]

David

···

On Sun, 21 Jun 2009, Hooopo wrote:

On Jun 21, 4:08 pm, Harry Kakueki <list.p...@gmail.com> wrote:

On Sun, Jun 21, 2009 at 4:10 PM, timr<timra...@gmail.com> wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
"Ruby 1.9: What You Need To Know" Envycasts with David A. Black
http://www.envycasts.com

Hi --

···

On Mon, 22 Jun 2009, Harry Kakueki wrote:

On Sun, Jun 21, 2009 at 9:26 PM, Sebastian > Hungerecker<sepp2k@googlemail.com> wrote:

"abcdefghijkl".scan(/(.)(?=(..))/).map(&:join)

=> ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]

HTH,
Sebastian

I am not the OP, but thanks for that solution.
I learned more about regular expressions and relearned something about scan.

It did not work on my machine so I changed it to this.
p "abcdefghijkl".scan(/(.)(?=(..))/).map{|x| x.join}

Is this map(&:join) using 1.9?

Yes. In general, &obj in that position triggers the use of obj.to_proc
as the code block for the method call, and in 1.9 there's a built-in
Symbol#to_proc method.

David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
"Ruby 1.9: What You Need To Know" Envycasts with David A. Black
http://www.envycasts.com

Hooopo wrote:

require'enumerator'
"qwertyuiopasdfgd".scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}

I see that it will not output anything if the scan is omitted but why is
that so? It seems that it does not buy us anything of value.

···

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

I have just realized where I have made a mistake!! I'm sorry for the fuss.

In message "Re: regular expression gurus--help!"

···

on 09/07/01, Nakagawa, Makoto (中川 誠) <Makoto.Nakagawa@hp.com> wrote:

  >>>> "abcdefghijkl".scan(/(.)(?=(..))/).map(&:join)
  >> => ["abc", "bcd", "cde", "def", "efg", "fgh", "ghi", "hij", "ijk", "jkl"]

  > I find this really interesting, but what version of Ruby is this? I am
  > not able to reproduce your result.

--
/*** Hewlett-Packard Japan, Ltd. ***/
/*** EDS Application Services ***/
/*** Consumer Industries & Retail, Department #4 ***/
/*** Nakagawa, Makoto(中川 誠) 050 3158 4747 (Dial-In) ***/
/*** PGP: 0B33 EAC3 F2F6 3D10 D9E9 AE7F 8EDA 44F9 1D29 D44A ***/

yet another solution

x.enum_for( :each_char ).each_cons( 3 ).map( &:join )

HTH
R.

···

--
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

Sorry for highjacking the thread, but I believe it served its purpose
well, already ;).

Please find a more readbale "mirror" of the following text here:
http://pastie.org/519985

Who feels with me that allowing you to do

coll.map( &:join )

but forbidding

coll.map( &:join, ", " )

is a shame.

Now it is clear that the above is not correct Ruby syntax. From my
experience very few people are fond of
the magic dot, which would solve the problem elegantly.

coll.map.join( ", " )

although in a very condensed way.

coll.map( ", ", &:join )

would be an alternative I kind of dislike.

Well burns down to

coll.map( :join, ", ")

And yes I know this is an old issue, but IIRC it has not been
discussed for some time :wink:

Cheers
Robert

···

On Mon, Jun 22, 2009 at 3:32 AM, David A. Black<dblack@rubypal.com> wrote:

Is this map(&:join) using 1.9?

Yes. In general, &obj in that position triggers the use of obj.to_proc
as the code block for the method call, and in 1.9 there's a built-in
Symbol#to_proc method.

--
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

Hooopo wrote:

require'enumerator'
"qwertyuiopasdfgd".scan(/./).each_cons(3){|x,y,z| p [x,y,z].join}

I see that it will not output anything if the scan is omitted but why is
that so? It seems that it does not buy us anything of value.

Because String has a somehow strange way to implement Enumerables in
1.8 and in 1.9 there is simply no String#each_cons (because String is
not an enumerable anymore)
Personally I think it was a good decision, forcing people to be clear
how they want the String to be "iterated"
as there are some possibilities
"".enum_for( x )
x in each_byte, each_char and ???
as a short for that you have
x.bytes --> Enumerator
x.chars --> Enumerator
But David has already applied this technique in one of the replies, so
I might not be DRY :wink:
HTH
Robert

Cheers

···

On Mon, Jun 22, 2009 at 8:32 PM, Lloyd Linklater<lloyd@2live4.com> wrote:

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

--
Toutes les grandes personnes ont d’abord été des enfants, mais peu
d’entre elles s’en souviennent.

All adults have been children first, but not many remember.

[Antoine de Saint-Exupéry]

Robert Dober wrote:

Who feels with me that allowing you to do

coll.map( &:join )

but forbidding

coll.map( &:join, ", " )

is a shame.

I think it's pretty ugly - especially the fact that you need the
argument ", " to be passed to join, not to map, and yet it appears in
map's argument list.

Now it is clear that the above is not correct Ruby syntax. From my
experience very few people are fond of
the magic dot, which would solve the problem elegantly.

coll.map.join( ", " )

although in a very condensed way.

That I dislike very much. What you want is to run a 'join' operation on
*each member* of the collection, but that looks like running a .map.join
on the *whole* collection. From that point of view,

  coll.map { |c| c.join(",") }

expresses very clearly what you're doing.

···

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