regex - Regular expression to stop at first match
Get the solution ↓↓↓My regex pattern looks something like
<xxxx location="file path/level1/level2" xxxx some="xxx">
I am only interested in the part in quotes assigned to location. Shouldn't it be as easy as below without the greedy switch?
/.*location="(.*)".*/
Does not seem to work.
Answer
Solution:
You need to make your regular expression lazy/non-greedy, because by default,"(.*)"
will match all of"file path/level1/level2" xxx some="xxx"
.
Instead you can make your dot-star non-greedy, which will make it match as few characters as possible:
/location="(.*?)"/
Adding a?
on a quantifier (?
,*
or+
) makes it non-greedy.
Note: this is only available in regex engines which implement the Perl 5 extensions (Java, Ruby, Python, etc) but not in "traditional" regex engines (including JavaScript, Awk,sed
,grep
without-P
, etc.).
Answer
Solution:
location="(.*)"
will match from the"
afterlocation=
until the"
aftersome="xxx
unless you make it non-greedy.
So you either need.*?
(i.e. make it non-greedy by adding?
) or better replace.*
with[^"]*
.
[^"]
Matches any character except for a " <quotation-mark>- More generic:
[^abc]
- Matches any character except for an a, b or c
Answer
Solution:
How about
.*location="([^"]*)".*
This avoids the unlimited search with .* and will match exactly to the first quote.
Answer
Solution:
Use non-greedy matching, if your engine supports it. Add the ? inside the capture.
/location="(.*?)"/
Answer
Solution:
Here's another way.
Here's the one you want. This is lazy[\s\S]*?
The first item:[\s\S]*?(?:location="[^"]*")[\s\S]*
Replace with:$1
Explaination: https://regex101.com/r/ZcqcUm/2
For completeness, this gets the last one. This is greedy[\s\S]*
The last item:[\s\S]*(?:location="([^"]*)")[\s\S]*
Replace with:$1
Explaination: https://regex101.com/r/LXSPDp/3
There's only 1 difference between these two regular expressions and that is the?
Answer
Solution:
Because you are using quantified subpattern and as descried in Perl Doc,
By default, a quantified subpattern is "greedy", that is, it will match as many times as possible (given a particular starting location) while still allowing the rest of the pattern to match. If you want it to match the minimum number of times possible, follow the quantifier with a "?" . Note that the meanings don't change, just the "greediness":
*? //Match 0 or more times, not greedily (minimum matches)
+? //Match 1 or more times, not greedily
Thus, to allow your quantified pattern to make minimum match, follow it by?
:
/location="(.*?)"/
Answer
Solution:
The other answers here fail to spell out a full solution for regex versions which don't support non-greedy matching. The greedy quantifiers ({-code-1}
,{-code-2}
etc) are a Perl 5 extension which isn't supported in traditional regular expressions.
If your stopping condition is a single character, the solution is easy; instead of
a({-code-1})b
you can match
{-code-4}
i.e specify a character class which excludes the {-code-6}ing and {-code-7}ing delimiiters.
In the more general case, you can painstakingly construct an expression like
{-code-5}
to capture a match between{-code-6}
and the first occurrence of{-code-7}
. Notice how the subexpression with nested parentheses spells out a number of alternatives which between them allowe
only if it isn't followed bynd
and so forth, and also take care to cover the empty string as one alternative which doesn't match whatever is disallowed at that particular point.
Of course, the correct approach in most cases is to use a proper parser for the format you are trying to parse, but sometimes, maybe one isn't available, or maybe the specialized tool you are using is insisting on a regular expression and nothing else.
Answer
Solution:
import regex
text = 'ask her to call Mary back when she comes back'
p = r'(?i)(?s)call(.*?)back'
for match in regex.finditer(p, str(text)):
print (match.group(1))
Output: Mary
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: warning: undefined array key
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.