Search code examples
regexmultilinenon-greedy

How to multiline regex but stop after first match?


I need to match any string that has certain characteristics, but I think enabling the /m flag is breaking the functionality.

What I know:

  1. The string will start and end with quotation marks.
  2. The string will have the following words. "the", "fox", and "lazy".
  3. The string may have a line break in the middle.
  4. The string will never have an at sign (used in the regex statement)

My problem is, if I have the string twice in a single block of text, it returns once, matching everything between the first quote mark and last quote mark with the required words in-between.

Here is my regex:

/^"the[^@]*fox[^@]*lazy[^@]*"$/gim

And a Regex101 example.

Here is my understanding of the statement. Match where the string starts with "the and there is the word fox and lazy (in that order) somewhere before the string ends with ". Also ignore newlines and case-sensitivity.

The most common answer to limiting is (.*?) But it doesn't work with new lines. And putting [^@?]* doesn't work because it adds the ? to the list of things to ignore.

So how can I keep the "match everything until ___" from skipping until the last instance while still being able to ignore newlines?

This is not a duplicate of anything else I can find because this deals with multi-line matching, and those don't.


Solution

  • In your case, all your quantifiers need to be non-greedy so you can just use the flag ungreedy: U.

    /^"the[^@]*fox[^@]*lazy[^@]*"$/gimU
    

    Example on Regex101.