Regex optional lookahead

I want the regex to match all of these:

  • startabcend
  • startdef
  • blahstartghiend
  • blahstartjklendsomething

and return abc , def , ghi and jkl respectively.

I have the following which works for cases 1 and 3, but I have problems with viewability.

 (?<=start).*(?=end.*) 

Edit:

Hm. Bad example. Actually, the bit in the middle is not numeric, but precedes a certain set of characters and, possibly, it succeeds. I updated the inputs and outputs on request and added a 4th example in response to some question.

+8
regex
source share
6 answers

Trying to read between the lines, it looks like you don’t want to look here, you really want not greedy .*? .

 (?<=start).*?(?:end)?$ 

I assume that you are trying to match something like "start123end" , but do not want end or start appear in the matching text, and thus you have converse statements there to restrict .* , Which is usually greedy.

Instead, you can use the unwanted option and snap the right end of the pattern with $ .

(Alternatively, if you can use capture groups, you should simply do this:

 start(.*?)(end)?$ 

and then just get the value from the first capture group.)

+8
source share

Maybe so:

 (?<=start).*?(?=(?:end|$)) 

This will match "start" and "end" or to the end of the line, in addition, the quantifier must not be greedy ( .*? )

See here at Regexr

The example in Regexr is increased to not only work with numbers.

+5
source share

Only Lookahead will not do the job. Try the following:

 (?<=start)(?:(?!end).)* 

When looking at a place you are after the word "start", then the rest consumes everything until (but not including) the next occurrence of the "end".

Here is a demo on Ideone.com

+2
source share

The optional lookahead does not make sense:

If this is optional, then it is normal if it matches, but it is also normal if it does not match. And since viewing does not increase the match, it has absolutely no effect.

So the syntax for an optional lookahead is an empty string.

+1
source share

If "end" will always be present, use: (?<=start)(.*?)(?=end) when you insert the OP. Since you say β€œmake it look optional,” then just run up until it comes to an β€œend” or carriage return. (?<=start)(.*?)(?=end|\n) . If you don't care about capturing the "end" group, can you skip the preview and do (?:start)?(.*?)(?:end)? which will start after "start" if it is there and stop to "end" if it is there. You can also use more such "or" patterns ": (?:start|^) and (?:end|\n) .

+1
source share

Why do you need a view?

 start(\d+)\w* 

Look at rubular

0
source share

All Articles