1

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.

Rahul Shrivastava
  • 1,189
  • 2
  • 11
  • 32

1 Answers1

1

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.
Community
  • 1
  • 1
Wiktor Stribiżew
  • 484,719
  • 26
  • 302
  • 397