0

I have a URL:

/ice-cream/stuff/sandwich/banana

I want to write a regular expression that ONLY matches the URL if these conditions are met:

  1. "ice-cream" is in the URL
  2. "sandwich" is in the URL and comes after "ice-cream"
  3. "banana" is NOT in the URL

I tried this: ice-cream.sandwich.^[(banana)] as well as many others but haven't found the solution.

Help is appreciate it.

1
  • It would be helpful to see example of strings (URL's) that match and those that don't (but come close). Also, what flavor are you using? Commented Jul 3, 2014 at 2:03

3 Answers 3

1

Give a try to the below regex,

^(?!.*banana.*).*?ice-cream.*?sandwich.*$

OR

^(?!.*banana.*)(?:(?!sandwich).)*ice-cream.*?sandwich.*$

DEMO

Explanation:

  • ^ Asserts that we are at the beginning of the line.
  • (?!.*banana.*) Negative lookahead which checks the line contain the string banana or not. If it's not then the regex engine set the marker on the starting. Or Otherwise it skips the lines which contains the string banana.
  • (?:(?!sandwich).)* Matches all the characters which are not of the string sandwich.
  • ice-cream.*?sandwich.* String sandwich must be after to the string ice-cream.
  • $ End of the line.
Sign up to request clarification or add additional context in comments.

5 Comments

Care to elaborate the difference, and how that (?!) thing (that the OP doesn't seem to know) works?
In your regex, why lazy (vs greedy) quantifiers?
@RonRosenfeld is there any difference if you remove the ? quantifier?
In testing against some samples, I did not see any difference in what was matched.
yep. don't care about the lazy or non-greedy quantifier. .* after sandwich will match everything.
1

Hard to be precise without examples of matches and non-matches, but give this a try:

^(?!.*banana)(?:(?!.*sandwich(?=.*ice-cream))).*ice-cream.*sandwich.*$

Explanation of Regex:

^(?!.*banana)(?:(?!.*sandwich(?=.*ice-cream))).*ice-cream.*sandwich.*$
----------------------------------------------------------------------

^(?!.*banana)(?:(?!.*sandwich(?=.*ice-cream))).*ice-cream.*sandwich.*$

Options: Case insensitive; Exact spacing; Dot doesn't match line breaks; ^$ match at line breaks; Default line breaks

Assert position at the beginning of a line «^»
Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!.*banana)»
   Match any single character that is NOT a line break character «.*»
      Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   Match the character string “banana” literally «banana»
Match the regular expression below «(?:(?!.*sandwich(?=.*ice-cream)))»
   Assert that it is impossible to match the regex below starting at this position (negative lookahead) «(?!.*sandwich(?=.*ice-cream))»
      Match any single character that is NOT a line break character «.*»
         Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
      Match the character string “sandwich” literally «sandwich»
      Assert that the regex below can be matched, starting at this position (positive lookahead) «(?=.*ice-cream)»
         Match any single character that is NOT a line break character «.*»
            Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
         Match the character string “ice-cream” literally «ice-cream»
Match any single character that is NOT a line break character «.*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character string “ice-cream” literally «ice-cream»
Match any single character that is NOT a line break character «.*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Match the character string “sandwich” literally «sandwich»
Match any single character that is NOT a line break character «.*»
   Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
Assert position at the end of a line «$»

Created with RegexBuddy

6 Comments

Care to explain/link that (?!) thing which seems to be new to the OP?
@Bergi Other's have explained the negative look-ahead.
Your regex wont match a string like /ice-cream/sandwich/stuff/ice-cream and its unclear what the OP wants.
@hwnd As designed. And I agree that the OP's requirements are not clear in the instance where sandwich both precedes and follows ice-cream. It also won't match /tuna/sandwich/ice-cream/sandwich If the OP does NOT want to exclude sandwich prior to ice-cream, so long as it exists after ice-cream, then it is just a matter of removing the 2nd "clause" from my regex, leaving it as ^(?!.*banana).*ice-cream.*sandwich.*$ (similar to Avinash Raj but without some of the "?"
Well, you can combine your lookaheads together. ^(?!.*(?:banana|sandwich(?=.*ice-cream))).*ice-cream.*sandwich.*$
|
-1
.*ice-cream.+sandwich.(?!banana).*

Try this one

1 Comment

Might be helpful to explain your code a bit, as others have done.

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.