2

I need to match a url path with that contain any of 2 words vendor_tracks or shop_types, but shop types should be followed by a ' / '

My current REGEX is

//(vendor_tracks|shop_types)/

, but this match if contain shop_types/22

I need my Regex to match something like :

/shop_types?q%5Btrack_department

but NOT the below url

/shop_types/27/list_pinned_vendors

My current accepts both, while I need it to accept only the first. I tried many different methods to exclude the "shop_types" followed by / but always get escaped backslash error. Any solution for this? or alternative REGEX

1
  • Evidently, in your first sentence, "should be followed" is missing the word "not". This is a pure-Ruby question so you should not have the "ruby-on-rails" tag. The tag "string" is so general I doubt that it serves any purpose. Commented Jan 20, 2019 at 17:56

1 Answer 1

2

You can use lookarounds to create custom restrictions

>> str1 = '/shop_types?q%5Btrack_department'
=> "/shop_types?q%5Btrack_department"
>> str2 = '/shop_types/27/list_pinned_vendors'
=> "/shop_types/27/list_pinned_vendors"

>> str1.match?(/shop_types(?!\/)/)
=> true
>> str2.match?(/shop_types(?!\/)/)
=> false

Here (?!\/) is negative lookahead which says that / character cannot be immediate character after shop_types

Note that end of string will also satisfy this condition as that would imply that there is no / character after shop_types


I tried many different methods to exclude the "shop_types" followed by / but always get escaped backslash error

You can use %r to define a regexp with alternate delimiters

# here the condition has also been changed
# restriction is that / shouldn't occur anywhere after matching shop_types
>> str1.match?(%r{shop_types(?!.*/)})
=> true
>> str2.match?(%r{shop_types(?!.*/)})
=> false
Sign up to request clarification or add additional context in comments.

1 Comment

In defining the negative lookahead you say, "...the character after shop_types...". That's misleading because a negative lookahead does not require the preceding match to be followed by a character; that is, the preceding match may be at the end of the string (e..g., "cat".match?(/t(?!z)/) #=> true. I'm sure you are aware of that, but you should say (sic), "...the preceding match is not followed...". imo, you should have ended your answer there. The last part answers two questions that were not asked. Yes, what you say may be helpful, but so might be answers to many other questions.

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.