# I need a string#all\_indices method--is there such a thing?

**URL:** <https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117>\
**Category:** ruby-talk\
**Created:** [28 August 2009 08:25 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117 "2009-08-28T08:25:08Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tim\_R](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@Tim\_R](https://rubytalk.org/u/Tim_R)\
**Post date:** [28 August 2009 08:25 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/1 "2009-08-28T08:25:08Z")

</div>

In ruby you can use string#index as follows:  
str = "some text"  
str.index(/t/)  
=\>5

But what if I want to get all the indices for a regex in the string?  
Is there an string#all\_indices method?

I wrote the following, which works, but there must be a more elegant  
way:

class String  
&nbsp;&nbsp;def all\_indices(regex)  
&nbsp;&nbsp;indices = []  
&nbsp;&nbsp;index = 0  
&nbsp;&nbsp;&nbsp;&nbsp;while index && index \< self.length #index will be nil upon first  
match failure, otherwise quit loop when index is equal to string  
length  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index = self.index(regex, index)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if index.is\_a? Numeric #avoids getting a nil into the indices  
array  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices \<\< index  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index +=1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;indices  
&nbsp;&nbsp;end  
end  
p "this is a test string for the ts in the worldt".all\_indices(/t/)  
p "what is up with all the twitter hype".all\_indices(/w/)  
# \>\> [0, 10, 13, 16, 26, 30, 36, 45]  
# \>\> [0, 11, 25]

---

<div class="post-metadata">

**Author:** ![Michal\_Zacik](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@Michal\_Zacik](https://rubytalk.org/u/Michal_Zacik)\
**Post date:** [28 August 2009 08:27 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/2 "2009-08-28T08:27:21Z")

</div>

scan

timr wrote:

> **···**
>
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?
> > 
> > I wrote the following, which works, but there must be a more elegant  
> > way:
> > 
> > class String  
> > &nbsp;&nbsp;def all\_indices(regex)  
> > &nbsp;&nbsp;indices =   
> > &nbsp;&nbsp;index = 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;while index && index \< self.length #index will be nil upon first  
> > match failure, otherwise quit loop when index is equal to string  
> > length  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index = self.index(regex, index)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if index.is\_a? Numeric #avoids getting a nil into the indices  
> > array  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices \<\< index  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index +=1  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;indices  
> > &nbsp;&nbsp;end  
> > end  
> > p "this is a test string for the ts in the worldt".all\_indices(/t/)  
> > p "what is up with all the twitter hype".all\_indices(/w/)  
> > # \>\> [0, 10, 13, 16, 26, 30, 36, 45]  
> > # \>\> [0, 11, 25]

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [28 August 2009 09:01 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/3 "2009-08-28T09:01:22Z")

</div>

What about  
class String  
&nbsp;&nbsp;def indices rgx, idx=0  
&nbsp;&nbsp;&nbsp;&nbsp;.tap{ |r|  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx = index rgx, idx  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break unless idx  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r \<\< idx  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx += 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;end  
end

p "baaababbabbbba".indices( /a/ )

> **···**
>
> On Fri, Aug 28, 2009 at 10:25 AM, timr\<timrandg@gmail.com\> wrote:
> 
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?
> > 
> > I wrote the following, which works, but there must be a more elegant  
> > way:
> > 
> > class String  
> > def all\_indices(regex)  
> > indices =   
> > index = 0  
> > while index && index \< self.length #index will be nil upon first  
> > match failure, otherwise quit loop when index is equal to string  
> > length  
> > index = self.index(regex, index)  
> > if index.is\_a? Numeric #avoids getting a nil into the indices  
> > array  
> > indices \<\< index  
> > index +=1  
> > end  
> > end  
> > indices  
> > end  
> > end  
> > p "this is a test string for the ts in the worldt".all\_indices(/t/)  
> > p "what is up with all the twitter hype".all\_indices(/w/)  
> > # \>\> [0, 10, 13, 16, 26, 30, 36, 45]  
> > # \>\> [0, 11, 25]
> 
> --  
> If you tell the truth you don't have to remember anything.  
> --  
> Samuel Clemens (some call him Mark Twain)

---

<div class="post-metadata">

**Author:** ![Harry3](https://avatars.discourse-cdn.com/v4/letter/h/54ee81/32.png) [@Harry3](https://rubytalk.org/u/Harry3)\
**Post date:** [28 August 2009 11:28 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/4 "2009-08-28T11:28:04Z")

</div>

Does this do what you want?

class String  
&nbsp;&nbsp;def all\_indices(reg)  
&nbsp;&nbsp;&nbsp;&nbsp;tmp,idx = ,  
&nbsp;&nbsp;&nbsp;&nbsp;(0...self.length).each{|x| tmp = self[x..-1]}  
&nbsp;&nbsp;&nbsp;&nbsp;tmp.each\_with\_index{|y,i| idx \<\< i if y =~ /\A#{reg}/}  
&nbsp;&nbsp;&nbsp;&nbsp;idx  
&nbsp;&nbsp;end  
end

p "this is a test string for the ts in the worldt".all\_indices(/th/)  
#\> [0, 26, 36]

It may not be very fast for very long strings ( I didn't check).  
But for strings like your example it seems OK.

Harry

> **···**
>
> On Fri, Aug 28, 2009 at 5:25 PM, timr\<timrandg@gmail.com\> wrote:
> 
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?
> 
> --  
> A Look into Japanese Ruby List in English
> 
> > **[Kakueki.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=kakueki.com)**
> >
> > Start using this domain right away. Straightforward domain shopping experience. Quick access to your domain.

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [28 August 2009 12:10 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/5 "2009-08-28T12:10:57Z")

</div>

Facets has:

&nbsp;&nbsp;def index\_all(s, reuse=false)  
&nbsp;&nbsp;&nbsp;&nbsp;s = Regexp.new(Regexp.escape(s)) unless Regexp===s  
&nbsp;&nbsp;&nbsp;&nbsp;ia = ; i = 0  
&nbsp;&nbsp;&nbsp;&nbsp;while (i = index(s,i))  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ia \<\< i  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i += (reuse ? 1 : $~[0].size)  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;ia  
&nbsp;&nbsp;end

> **···**
>
> On Aug 28, 4:25 am, timr \<timra...@gmail.com\> wrote:
> 
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?

---

<div class="post-metadata">

**Author:** ![Shot\_Piotr\_Szotkowsk](https://avatars.discourse-cdn.com/v4/letter/s/c5a1d2/32.png) [@Shot\_Piotr\_Szotkowsk](https://rubytalk.org/u/Shot_Piotr_Szotkowsk)\
**Post date:** [28 August 2009 15:36 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/6 "2009-08-28T15:36:20Z")

</div>

timr:

> But what if I want to get all the indices for a regex  
> in the string? Is there an string#all\_indices method?

How about the below?

class String  
&nbsp;&nbsp;def all\_indices needle  
&nbsp;&nbsp;&nbsp;&nbsp;all =   
&nbsp;&nbsp;&nbsp;&nbsp;offset = 0  
&nbsp;&nbsp;&nbsp;&nbsp;loop do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;i = index needle, offset  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break if i.nil?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;all \<\< i  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;offset = i + 1  
&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;all  
&nbsp;&nbsp;end  
end

— Shot

> **···**
>
> --  
> It may look like I’m just sitting here doing nothing. But  
> I’m really actively waiting for all my problems to go away.

---

<div class="post-metadata">

**Author:** ![Glenn\_Jackman](https://avatars.discourse-cdn.com/v4/letter/g/ce73a5/32.png) [@Glenn\_Jackman](https://rubytalk.org/u/Glenn_Jackman)\
**Post date:** [28 August 2009 16:46 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/7 "2009-08-28T16:46:01Z")

</div>

This is a bit simpler:  
&nbsp;&nbsp;&nbsp;&nbsp;class String  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def all\_indices(substring)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx = 0  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices =   
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loop do  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx = index(substring, idx)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;break if idx.nil?  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices \<\< idx  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;idx += 1  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

&nbsp;&nbsp;&nbsp;&nbsp;require 'test/unit'  
&nbsp;&nbsp;&nbsp;&nbsp;class TestAllIndices \< Test::Unit::TestCase  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;def test\_it  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[0, 10, 13, 16, 26, 30, 36, 45],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"this is a test string for the ts in the worldt".all\_indices(/t/)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[0, 11, 25],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"what is up with all the twitter hype".all\_indices(/w/)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[12, 17, 26, 41],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"the quick brown fox jumps over the lazy dog".all\_indices('o')  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;assert\_equal(  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[1, 3, 5],  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"bananana".all\_indices('ana')  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
&nbsp;&nbsp;&nbsp;&nbsp;end

> **···**
>
> At 2009-08-28 04:20AM, "timr" wrote:
> 
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?
> > 
> > I wrote the following, which works, but there must be a more elegant  
> > way:
> > 
> > class String  
> > &nbsp;&nbsp;&nbsp;def all\_indices(regex)  
> > &nbsp;&nbsp;&nbsp;indices =   
> > &nbsp;&nbsp;&nbsp;index = 0  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while index && index \< self.length #index will be nil upon first  
> > match failure, otherwise quit loop when index is equal to string  
> > length  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index = self.index(regex, index)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if index.is\_a? Numeric #avoids getting a nil into the indices  
> > array  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices \<\< index  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;index +=1  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;indices  
> > &nbsp;&nbsp;&nbsp;end  
> > end  
> > p "this is a test string for the ts in the worldt".all\_indices(/t/)  
> > p "what is up with all the twitter hype".all\_indices(/w/)  
> > # \>\> [0, 10, 13, 16, 26, 30, 36, 45]  
> > # \>\> [0, 11, 25]
> 
> --  
> Glenn Jackman  
> &nbsp;&nbsp;&nbsp;&nbsp;Write a wise saying and your name will live forever. -- Anonymous

---

<div class="post-metadata">

**Author:** ![7rans](https://avatars.discourse-cdn.com/v4/letter/7/a8b319/32.png) [@7rans](https://rubytalk.org/u/7rans)\
**Post date:** [29 August 2009 02:38 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/8 "2009-08-29T02:38:19Z")

</div>

A lot of solutions have been given here. It would be nice to see a  
test/benchmark matrix to compare them, if anyone is up to it.

> **···**
>
> On Aug 28, 4:25 am, timr \<timra...@gmail.com\> wrote:
> 
> > In ruby you can use string#index as follows:  
> > str = "some text"  
> > str.index(/t/)  
> > =\>5
> > 
> > But what if I want to get all the indices for a regex in the string?  
> > Is there an string#all\_indices method?

---

<div class="post-metadata">

**Author:** ![Tim\_R](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@Tim\_R](https://rubytalk.org/u/Tim_R)\
**Post date:** [28 August 2009 08:40 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/9 "2009-08-28T08:40:05Z")

</div>

Scan gives you the matches, not the indices (which is what I need).

> > "this is a test for scan".scan(/t/)

=\> ["t", "t", "t"]

---

<div class="post-metadata">

**Author:** ![Harry3](https://avatars.discourse-cdn.com/v4/letter/h/54ee81/32.png) [@Harry3](https://rubytalk.org/u/Harry3)\
**Post date:** [28 August 2009 12:02 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/10 "2009-08-28T12:02:32Z")

</div>

> Does this do what you want?
> 
> class String  
> def all\_indices(reg)  
> &nbsp;&nbsp;&nbsp;tmp,idx = ,  
> &nbsp;&nbsp;&nbsp;(0...self.length).each{|x| tmp = self[x..-1]}  
> &nbsp;&nbsp;&nbsp;tmp.each\_with\_index{|y,i| idx \<\< i if y =~ /\A#{reg}/}  
> &nbsp;&nbsp;&nbsp;idx  
> end  
> end
> 
> p "this is a test string for the ts in the worldt".all\_indices(/th/)  
> #\> [0, 26, 36]
> 
> Harry

Sorry, it looks like I had an unnecessary line in there.

class String  
&nbsp;&nbsp;def all\_indices(reg)  
&nbsp;&nbsp;&nbsp;&nbsp;idx =   
&nbsp;&nbsp;&nbsp;&nbsp;(0...self.length).each{|x| idx \<\< x if self[x..-1] =~ /\A#{reg}/}  
&nbsp;&nbsp;&nbsp;&nbsp;idx  
&nbsp;&nbsp;end  
end

p "this is a test string for the ts in the worldt".all\_indices(/th/)  
#\> [0, 26, 36]  
p "banana".all\_indices(/ana/) #\> [1, 3]

Harry

> **···**
>
> --  
> A Look into Japanese Ruby List in English
> 
> > **[Kakueki.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=kakueki.com)**
> >
> > Start using this domain right away. Straightforward domain shopping experience. Quick access to your domain.

---

<div class="post-metadata">

**Author:** ![Tim\_R](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@Tim\_R](https://rubytalk.org/u/Tim_R)\
**Post date:** [28 August 2009 14:55 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/11 "2009-08-28T14:55:12Z")

</div>

> What about  
> class String  
> def indices rgx, idx=0  
> .tap{ |r|  
> loop do  
> idx = index rgx, idx  
> break unless idx  
> r \<\< idx  
> idx += 1  
> end  
> }  
> end  
> end

.tap?  
you must have defined a tap method for array somewhere. But not in the  
code you showed. Can't run the code without a definition for tap.  
Thanks,  
Tim

---

<div class="post-metadata">

**Author:** ![Tim\_R](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@Tim\_R](https://rubytalk.org/u/Tim_R)\
**Post date:** [28 August 2009 15:00 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/12 "2009-08-28T15:00:05Z")

</div>

Oh, tap is new in 1.9. Sorry, I hadn't come across it before and was  
in 1.8.6 so it wasn't running. Got it now.

> **···**
>
> On Aug 28, 2:01 am, Robert Dober \<robert.do...@gmail.com\> wrote:
> 
> > On Fri, Aug 28, 2009 at 10:25 AM, timr\<timra...@gmail.com\> wrote:  
> > \> In ruby you can use string#index as follows:  
> > \> str = "some text"  
> > \> str.index(/t/)  
> > \> =\>5
> > 
> > \> But what if I want to get all the indices for a regex in the string?  
> > \> Is there an string#all\_indices method?
> > 
> > \> I wrote the following, which works, but there must be a more elegant  
> > \> way:
> > 
> > \> class String  
> > \> def all\_indices(regex)  
> > \> indices =   
> > \> index = 0  
> > \> while index && index \< self.length #index will be nil upon first  
> > \> match failure, otherwise quit loop when index is equal to string  
> > \> length  
> > \> index = self.index(regex, index)  
> > \> if index.is\_a? Numeric #avoids getting a nil into the indices  
> > \> array  
> > \> indices \<\< index  
> > \> index +=1  
> > \> end  
> > \> end  
> > \> indices  
> > \> end  
> > \> end  
> > \> p "this is a test string for the ts in the worldt".all\_indices(/t/)  
> > \> p "what is up with all the twitter hype".all\_indices(/w/)  
> > \> # \>\> [0, 10, 13, 16, 26, 30, 36, 45]  
> > \> # \>\> [0, 11, 25]
> > 
> > What about  
> > class String  
> > def indices rgx, idx=0  
> > .tap{ |r|  
> > loop do  
> > idx = index rgx, idx  
> > break unless idx  
> > r \<\< idx  
> > idx += 1  
> > end  
> > }  
> > end  
> > end
> > 
> > p "baaababbabbbba".indices( /a/ )
> > 
> > --  
> > If you tell the truth you don't have to remember anything.  
> > --  
> > Samuel Clemens (some call him Mark Twain)

---

<div class="post-metadata">

**Author:** ![Bertram\_Scharpf](https://avatars.discourse-cdn.com/v4/letter/b/43a26b/32.png) [@Bertram\_Scharpf](https://rubytalk.org/u/Bertram_Scharpf)\
**Post date:** [29 August 2009 05:00 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/13 "2009-08-29T05:00:38Z")

</div>

Hi,

> **···**
>
> Am Samstag, 29. Aug 2009, 11:38:19 +0900 schrieb 7rans:
> 
> > On Aug 28, 4:25 am, timr \<timra...@gmail.com\> wrote:
> > 
> > A lot of solutions have been given here. It would be nice to see a  
> > test/benchmark matrix to compare them, if anyone is up to it.
> 
> Sure I agree. But my solution was just to show some aspect of  
> String#scan, not of any practical sense.
> 
> Bertram
> 
> --  
> Bertram Scharpf  
> Stuttgart, Deutschland/Germany  
> [http://www.bertram-scharpf.de](http://www.bertram-scharpf.de)

---

<div class="post-metadata">

**Author:** ![Michal\_Zacik](https://avatars.discourse-cdn.com/v4/letter/m/53a042/32.png) [@Michal\_Zacik](https://rubytalk.org/u/Michal_Zacik)\
**Post date:** [28 August 2009 08:47 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/14 "2009-08-28T08:47:44Z")

</div>

Sorry, bad idea.

timr wrote:

> **···**
>
> > Scan gives you the matches, not the indices (which is what I need).
> > 
> > > > "this is a test for scan".scan(/t/)  
> > > > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
> > 
> > =\> ["t", "t", "t"]

---

<div class="post-metadata">

**Author:** ![Bertram\_Scharpf](https://avatars.discourse-cdn.com/v4/letter/b/43a26b/32.png) [@Bertram\_Scharpf](https://rubytalk.org/u/Bertram_Scharpf)\
**Post date:** [28 August 2009 09:13 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/15 "2009-08-28T09:13:56Z")

</div>

Hi,

> Scan gives you the matches, not the indices (which is what I need).
> 
> \>\> "this is a test for scan".scan(/t/)  
> =\> ["t", "t", "t"]

There's a trick to do it with String#scan:

&nbsp;&nbsp;a =   
&nbsp;&nbsp;"this is a test for scan".scan( /t/) { a.push $`.length }  
&nbsp;&nbsp;a

This does not work when the matches overlap.

&nbsp;&nbsp;"banana".scan /ana/ #=\> ["ana"]

Bertram

> **···**
>
> Am Freitag, 28. Aug 2009, 17:40:05 +0900 schrieb timr:
> 
> --  
> Bertram Scharpf  
> Stuttgart, Deutschland/Germany  
> [http://www.bertram-scharpf.de](http://www.bertram-scharpf.de)

---

<div class="post-metadata">

**Author:** ![Tim\_R](https://avatars.discourse-cdn.com/v4/letter/t/ecc23a/32.png) [@Tim\_R](https://rubytalk.org/u/Tim_R)\
**Post date:** [28 August 2009 15:05 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/16 "2009-08-28T15:05:05Z")

</div>

This works and the code is more concise than what I had, but it is a  
brute force approach that test for matches from every possible  
substring. That would be a bit slow.

> **···**
>
> On Aug 28, 5:02 am, Harry Kakueki \<list.p...@gmail.com\> wrote:
> 
> > \> Does this do what you want?
> > 
> > \> class String  
> > \> def all\_indices(reg)  
> > \> tmp,idx = ,  
> > \> (0...self.length).each{|x| tmp = self[x..-1]}  
> > \> tmp.each\_with\_index{|y,i| idx \<\< i if y =~ /\A#{reg}/}  
> > \> idx  
> > \> end  
> > \> end
> > 
> > \> p "this is a test string for the ts in the worldt".all\_indices(/th/)  
> > \> #\> [0, 26, 36]
> > 
> > \> Harry
> > 
> > Sorry, it looks like I had an unnecessary line in there.
> > 
> > class String  
> > def all\_indices(reg)  
> > idx =   
> > (0...self.length).each{|x| idx \<\< x if self[x..-1] =~ /\A#{reg}/}  
> > idx  
> > end  
> > end
> > 
> > p "this is a test string for the ts in the worldt".all\_indices(/th/)  
> > #\> [0, 26, 36]  
> > p "banana".all\_indices(/ana/) #\> [1, 3]
> > 
> > Harry
> > 
> > --  
> > A Look into Japanese Ruby List in Englishhttp://www.kakueki.com/ruby/list.html

---

<div class="post-metadata">

**Author:** ![Forum](https://avatars.discourse-cdn.com/v4/letter/f/43a26b/32.png) [@Forum](https://rubytalk.org/u/Forum)\
**Post date:** [28 August 2009 21:27 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/17 "2009-08-28T21:27:22Z")

</div>

Sorry I am an unconditional one-niner. I really should be more careful  
to mark 1.9 only features with comments. At least for some more weeks  
😉

> **···**
>
> On Fri, Aug 28, 2009 at 4:55 PM, timr\<timrandg@gmail.com\> wrote:
> 
> > > What about  
> > > class String  
> > > def indices rgx, idx=0  
> > > .tap{ |r|  
> > > loop do  
> > > idx = index rgx, idx  
> > > break unless idx  
> > > r \<\< idx  
> > > idx += 1  
> > > end  
> > > }  
> > > end  
> > > end
> > 
> > .tap?  
> > you must have defined a tap method for array somewhere. But not in the  
> > code you showed. Can't run the code without a definition for tap.  
> > Thanks,  
> > Tim
> 
> --  
> If you tell the truth you don't have to remember anything.  
> --  
> Samuel Clemens (some call him Mark Twain)

---

<div class="post-metadata">

**Author:** ![David\_A\_Black1](https://avatars.discourse-cdn.com/v4/letter/d/bcef8e/32.png) [@David\_A\_Black1](https://rubytalk.org/u/David_A_Black1)\
**Post date:** [28 August 2009 23:02 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/18 "2009-08-28T23:02:05Z")

</div>

Hi --

> class String  
> def all\_indices(reg)  
> &nbsp;&nbsp;&nbsp;idx =   
> &nbsp;&nbsp;&nbsp;(0...self.length).each{|x| idx \<\< x if self[x..-1] =~ /\A#{reg}/}  
> &nbsp;&nbsp;&nbsp;idx  
> end  
> end

Might as well let #select do the choosing:

&nbsp;&nbsp;&nbsp;def all\_indices(re)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0...size).select {|i| self[i..-1][/\A#{re}/] }  
&nbsp;&nbsp;&nbsp;end

And maybe better to create the regex only one:

&nbsp;&nbsp;&nbsp;def all\_indices(re)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;re = /\A#{re}/  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(0...size).select {|i| self[i..-1][re] }  
&nbsp;&nbsp;&nbsp;end

David

> **···**
>
> On Fri, 28 Aug 2009, Harry Kakueki wrote:
> 
> --  
> David A. Black / Ruby Power and Light, LLC / [http://www.rubypal.com](http://www.rubypal.com)  
> Ruby/Rails training, mentoring, consulting, code-review  
> Latest book: The Well-Grounded Rubyist ([http://www.manning.com/black2\](http://www.manning.com/black2%5C))
> 
> September Ruby training in NJ has been POSTPONED. Details to follow.

---

<div class="post-metadata">

**Author:** ![Joel\_VanderWerf1](https://avatars.discourse-cdn.com/v4/letter/j/94ad74/32.png) [@Joel\_VanderWerf1](https://rubytalk.org/u/Joel_VanderWerf1)\
**Post date:** [28 August 2009 21:08 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/19 "2009-08-28T21:08:29Z")

</div>

Bertram Scharpf wrote:

> Hi,
> 
> > Scan gives you the matches, not the indices (which is what I need).
> > 
> > > > "this is a test for scan".scan(/t/)
> > 
> > =\> ["t", "t", "t"]
> 
> There's a trick to do it with String#scan:
> 
> &nbsp;&nbsp;a =   
> &nbsp;&nbsp;"this is a test for scan".scan( /t/) { a.push $`.length }  
> &nbsp;&nbsp;a
> 
> This does not work when the matches overlap.
> 
> &nbsp;&nbsp;"banana".scan /ana/ #=\> ["ana"]
> 
> Bertram

Same difficulty with overlap, but for variety:

class String  
&nbsp;&nbsp;&nbsp;def all\_indexes re  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a=;scan(re) {a\<\<$~.begin(0)};a  
&nbsp;&nbsp;&nbsp;end  
end

p "foo bar baz".all\_indexes(/.../)  
p "banana".all\_indexes(/ana/)

\_\_END\_\_

Output:

[0, 3, 6]  
[1]

> **···**
>
> > Am Freitag, 28. Aug 2009, 17:40:05 +0900 schrieb timr:
> 
> --  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

---

<div class="post-metadata">

**Author:** ![Harry3](https://avatars.discourse-cdn.com/v4/letter/h/54ee81/32.png) [@Harry3](https://rubytalk.org/u/Harry3)\
**Post date:** [28 August 2009 22:21 UTC](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117/20 "2009-08-28T22:21:17Z")

</div>

This is not fast enough?

class String  
&nbsp;&nbsp;def all\_indices(reg)  
&nbsp;&nbsp;&nbsp;&nbsp;idx =   
&nbsp;&nbsp;&nbsp;&nbsp;(0...self.length).each{|x| idx \<\< x if self[x..-1] =~ /\A#{reg}/}  
&nbsp;&nbsp;&nbsp;&nbsp;idx  
&nbsp;&nbsp;end  
end

p ("this is a test string for the ts in the worldt"\*1000).all\_indices(/th/)

I guess you are processing some big strings.  
Speed is not what you asked for.  
Well, until now 🙂

Harry

> **···**
>
> On Sat, Aug 29, 2009 at 12:05 AM, timr\<timrandg@gmail.com\> wrote:
> 
> > On Aug 28, 5:02 am, Harry Kakueki \<list.p...@gmail.com\> wrote:
> > 
> > > class String  
> > > &nbsp;&nbsp;def all\_indices(reg)  
> > > &nbsp;&nbsp;&nbsp;&nbsp;idx =   
> > > &nbsp;&nbsp;&nbsp;&nbsp;(0...self.length).each{|x| idx \<\< x if self[x..-1] =~ /\A#{reg}/}  
> > > &nbsp;&nbsp;&nbsp;&nbsp;idx  
> > > &nbsp;&nbsp;end  
> > > end
> > > 
> > > p "this is a test string for the ts in the worldt".all\_indices(/th/)  
> > > #\> [0, 26, 36]  
> > > p "banana".all\_indices(/ana/) #\> [1, 3]
> > > 
> > > Harry
> > 
> > This works and the code is more concise than what I had, but it is a  
> > brute force approach that test for matches from every possible  
> > substring. That would be a bit slow.
> 
> --  
> A Look into Japanese Ruby List in English
> 
> > **[Kakueki.com is for sale | HugeDomains](https://www.hugedomains.com/domain_profile.cfm?d=kakueki.com)**
> >
> > Start using this domain right away. Straightforward domain shopping experience. Quick access to your domain.

[Next page](https://rubytalk.org/t/i-need-a-string-all-indices-method-is-there-such-a-thing/55117.md?page=2)
