1

Say, i have a following string

string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "

I want o/p as

"#Sachin|0|7;#Tendulkar|29|10;#Sachinn|63|7;"

I tried following

 new_string = ""
 string.scan(/#\S+/).each{|match| new_string+="#{match}|#{string.index(match)}|#{match.length};"  }

which gives me

 "#Sachin|0|7;#Tendulkar|29|10;#Sachin|0|7;" 

So how i will get the starting index of each sub-string?

Salil
  • 46,566
  • 21
  • 122
  • 156

3 Answers3

3

This is actually quite a non-trivial task, and has been discussed quite a bit in other questions on SO. This is the most common solution:

string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "
new_string = string.to_enum(:scan,/#\S+/i).inject(''){|s,m| s + "#{m}|#{$`.size}|#{m.length};"}
Mike Campbell
  • 7,921
  • 2
  • 38
  • 51
  • 1
    +1 and deleted my answer :) You could make your solution even simpler with inject - string.to_enum(:scan,/#\S+/i).inject('') { |s,m| s + "#{m}|#{$`.size}|#{m.length};" } – trushkevich Jun 19 '13 at 09:09
  • Not sure it helps for the reading, but it was fairly illegible anyway so I've updated :). Thanks. – Mike Campbell Jun 19 '13 at 09:11
1

Based on this thread How do I get the match data for all occurrences of a Ruby regular expression in a string? just quick example:

string = "#Sachin is Indian cricketer. #Tendulkar is right hand batsman. #Sachin has been honoured with the Padma Vibhushan award "
new_string = ""
string
  .to_enum(:scan, /#\S+/)
  .each do |wrd|
    m = Regexp.last_match
    new_string += "#{wrd}|#{m.offset(0)[0]}|#{wrd.length};"
  end
p new_string
Community
  • 1
  • 1
Yevgeniy Anfilofyev
  • 4,827
  • 25
  • 27
1

Here's one that uses scan:

offset = 0
string.scan(/(#\S*)([^#]*)/).map{|m| v = "#{m[0]}|#{offset}|#{m[0].length};"; offset += m.join.length; v}.join
#=> "#Sachin|0|7;#Tendulkar|29|10;#Sachin|63|7;"
pguardiario
  • 53,827
  • 19
  • 119
  • 159