2

While this code run perfectly:

def center2 (a)
  c = a.match('(?<=A).*$')
  return c
end

Why this code got an error:

def center2 (a)
  b = a.match('(?<=_).*$')
  c = b.match('(?<=A).*$')
  return c
end

with this error

undefined method `match', Did you mean? catch

4
  • 1
    What is this code supposed to do? Commented Aug 4, 2017 at 13:43
  • first regex supposed to get all the string after first '_' and before last '.', and for then for the result I was trying to use another regex which get all string after 'A'. Commented Aug 4, 2017 at 14:07
  • @Stefan problem is solved now. the match function doesn't return the string, but the matchdata object. So I need to use the second match function on the first element. Commented Aug 4, 2017 at 14:08
  • negams, you still haven't answered @Stefan's question (nevermind that there is an accepted solution). Since your code raises an exception how is the reader supposed to figure out what you are trying to achieve? You should edit to state (at the beginning) your objective. Commented Aug 4, 2017 at 18:06

2 Answers 2

5

The match method returns a MatchData object (or nil if there was no match). You seem to want to run the second match on the first match string value. So, just use

def center2 (a)
  b = a[/(?<=_).*$/]
  c = b[/(?<=A).*$/]
end

See the Ruby demo

Actually, if these patterns are placeholders for more complicated patterns, and the task is to find a substring after the first _ and then the rightmost A, you may shorten this code to

def center2 (a)
  a[/_.*?A\K.*/]
end

See this Ruby demo. Do not forget about m modifier if you need to match across lines (. does not match line breaks by default). _ will match the first _ from the left, .*?A will match any 0+ chars as few as possible up to and including the closest A and \K will omit the matched text and .* will match and return any 0+ chars (other than line break chars by default).

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you, this works. I suppose I was performing the second match function on a list and not on a string. Thank you.
Wiktor used \K ("forget everything matched so far") rather than /(?<=_.*?A).*/ because Ruby does not support variable-length lookbehinds (lookaheads OK). Alternatively, one could use a capture group: a[/_.*?A(.*)/, 1].
1

It is not necessary to use a regular expression.

def grab_end(str)
  idx_ = str.index('_')
  idxA = str.rindex('A')
  idx_ && idxA && (idx_ < idxA) && str[str.rindex('A')+1..-1]
end

grab_end "Now and_then I_like Aeating popcorn" #=> "eating popcorn"
grab_end "Now and_then I_like eating popcorn"  #=> nil
grab_end "Now and then I like Aeating popcorn" #=> nil
grab_end "Now and then I like Aeating_popcorn" #=> false

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.