joshnabbott
joshnabbott

Reputation: 137

Using positive lookahead in Ruby

I'm writing a regular expression for the following phrase variations:

I'm capturing two things: the word "greater" or "less" and the amount. I want to capture the amount whether there's a dollar sign in it or not, but this is what's tripping me up.

Here's my regexp:

/^.*(?=cart total).*(?=(greater|less)).*(?=\$([0-9.]+))/

This:

"cart total is greater than $5.00".match(/^.*(?=cart total).*(?=(greater|less)).*(?=\$([0-9.]+))/)

gets me "greater" and 5.00 but this:

    "cart total is greater than 5.00".match(/^.*(?=cart total).*(?=(greater|less)).*(?=\$([0-9.]+))/)

get me "greater" and ""

I realize the lookahead is searching specifcally for the "$" in the group so taking it out causes it not to find the amount, but I'd love to see how to modify this to find the amount regardless of the presence of "$" or not.

Thanks!

Upvotes: 2

Views: 540

Answers (3)

Daniël Knippers
Daniël Knippers

Reputation: 3055

The lookahead is not necessary in this case. I improved your dollar matching slightly to also match with commas in the number, e.g., $1,000.00, and without any commas / decimal points, e.g., $10.

regex = /cart total is (greater|less) than \$?((?:\d+,?)+(?:.\d+)?)/

strings = [
  "cart total is greater than 5.00",
  "cart total is less than $1,500,000.00",
  "cart total is greater than $5"
]

strings.each do |string|
  p string.match(regex)
end

#<MatchData "cart total is greater than 5.00" 1:"greater" 2:"5.00">
#<MatchData "cart total is less than $1,500,000.00" 1:"less" 2:"1,500,000.00">
#<MatchData "cart total is greater than $5" 1:"greater" 2:"5">

Upvotes: 3

Kamehameha
Kamehameha

Reputation: 5473

You can use the optional quantifier ?.
A small modification to your original regex-

^.*(?=cart total).*(?=(greater|less)).*(?=\$?([0-9.]+))
                                            ^ Added ?

Demo here

Upvotes: 1

Sabuj Hassan
Sabuj Hassan

Reputation: 39355

To me lookahead is unnecessary in this case. I have removed those. And added \$? for optional dollar sign.

^.*?cart total.*?(greater|less).*?\$?([0-9.]+)

Upvotes: 5

Related Questions