Reputation: 1411
String = I <am a insta good </boy>.Why,I <am a insta bad </boy>.Where,I <am a naughty </boy>.How,I <am a soft </toy>.Don't know,I <am a very good </boy>.Why so, I <am a very bad </boy>.That's why
I want output where insta is between these two words like this
<am a insta good </boy>
<am a insta bad </boy>
I tried /(<am)(.*)(<\/boy>)/g
this but I am getting many output. Not what I want means those 5 lines.
Upvotes: 1
Views: 51
Reputation: 627488
Since you want to get a substring between 2 strings not having a third substring in between, your only 1-pass regex solution is using a tempered greedy token. See these best practice guidelines:
When to Use this Technique
Suppose our boss now tells us that we still want to match up to and including{END}
, but that we also need to avoid stepping over a{MID}
section, if it exists. Starting with the lazy dot-star version to ensure we match up to the{END}
delimiter, we can then temper the dot to ensure it doesn't roll over{MID}
:
{START}(?:(?!{MID}).)*?{END}
/(<am)((?:(?!<am|<\/boy>|insta).)*insta.*?)(<\/boy>)/g
See the regex demo
Note I kept the capturing groups intact, feel free to keep only those you need.
Pattern details:
(<am)
- <am
substring(?:(?!<am|<\/boy>|insta).)*
- the tempered greedy token matching any char but a line break char .
that does not start any of the sequences defined in the negative lookahead: <am
, </boy>
or insta
insta
- an insta
substring.*?
- any 0+ chars other than line break chars(<\/boy>)
- </boy>
substring.Upvotes: 1