CINXE.COM

Regex to Test The Same Part of The String for More Than One Requirement

<!DOCTYPE html> <html lang="en"><head><meta charset="utf-8"><link rel=canonical href='https://https://www.regular-expressions.info//lookaround2.html'><title>Regex to Test The Same Part of The String for More Than One Requirement</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="author" content="Jan Goyvaerts"> <meta name="description" content="With lookaround, you can have a regular expression test the same part of the string for more than one requirement, expressed in a sub-regex."> <meta name="keywords" content=""> <link rel=stylesheet href="regex.css" type="text/css"><script src="theme.js" type="text/javascript"></script><link rel="alternate" type="application/rss+xml" title="New at Regular-Expressions.info" href="updates.xml"> </head> <body bgcolor=white text=black> <div id=top></div> <div id=btntop><div id=btngrid><a href="quickstart.html" target="_top"><div>Quick&nbsp;Start</div></a><a href="tutorial.html" target="_top"><div>Tutorial</div></a><a href="tools.html" target="_top"><div>Tools&nbsp;&amp;&nbsp;Languages</div></a><a href="examples.html" target="_top"><div>Examples</div></a><a href="refflavors.html" target="_top"><div>Reference</div></a><a href="books.html" target="_top"><div>Book&nbsp;Reviews</div></a></div></div> <div id=contents><div id=side> <TABLE CLASS=side CELLSPACING=0 CELLPADDING=4><TR><TD CLASS=sideheader>Regex Tutorial</TD></TR><TR><TD><A HREF="tutorial.html" TARGET=_top>Introduction</A></TD></TR><TR><TD><A HREF="tutorialcnt.html" TARGET=_top>Table of Contents</A></TD></TR><TR><TD><A HREF="characters.html" TARGET=_top>Special Characters</A></TD></TR><TR><TD><A HREF="nonprint.html" TARGET=_top>Non-Printable Characters</A></TD></TR><TR><TD><A HREF="engine.html" TARGET=_top>Regex Engine Internals</A></TD></TR><TR><TD><A HREF="charclass.html" TARGET=_top>Character Classes</A></TD></TR><TR><TD><A HREF="charclasssubtract.html" TARGET=_top>Character Class Subtraction</A></TD></TR><TR><TD><A HREF="charclassintersect.html" TARGET=_top>Character Class Intersection</A></TD></TR><TR><TD><A HREF="shorthand.html" TARGET=_top>Shorthand Character Classes</A></TD></TR><TR><TD><A HREF="dot.html" TARGET=_top>Dot</A></TD></TR><TR><TD><A HREF="anchors.html" TARGET=_top>Anchors</A></TD></TR><TR><TD><A HREF="wordboundaries.html" TARGET=_top>Word Boundaries</A></TD></TR><TR><TD><A HREF="alternation.html" TARGET=_top>Alternation</A></TD></TR><TR><TD><A HREF="optional.html" TARGET=_top>Optional Items</A></TD></TR><TR><TD><A HREF="repeat.html" TARGET=_top>Repetition</A></TD></TR><TR><TD><A HREF="brackets.html" TARGET=_top>Grouping &amp; Capturing</A></TD></TR><TR><TD><A HREF="backref.html" TARGET=_top>Backreferences</A></TD></TR><TR><TD><A HREF="backref2.html" TARGET=_top>Backreferences, part 2</A></TD></TR><TR><TD><A HREF="named.html" TARGET=_top>Named Groups</A></TD></TR><TR><TD><A HREF="backrefrel.html" TARGET=_top>Relative Backreferences</A></TD></TR><TR><TD><A HREF="branchreset.html" TARGET=_top>Branch Reset Groups</A></TD></TR><TR><TD><A HREF="freespacing.html" TARGET=_top>Free-Spacing &amp; Comments</A></TD></TR><TR><TD><A HREF="unicode.html" TARGET=_top>Unicode</A></TD></TR><TR><TD><A HREF="modifiers.html" TARGET=_top>Mode Modifiers</A></TD></TR><TR><TD><A HREF="atomic.html" TARGET=_top>Atomic Grouping</A></TD></TR><TR><TD><A HREF="possessive.html" TARGET=_top>Possessive Quantifiers</A></TD></TR><TR><TD><A HREF="lookaround.html" TARGET=_top>Lookahead &amp; Lookbehind</A></TD></TR><TR><TD><A HREF="lookaround2.html" TARGET=_top>Lookaround, part 2</A></TD></TR><TR><TD><A HREF="keep.html" TARGET=_top>Keep Text out of The Match</A></TD></TR><TR><TD><A HREF="conditional.html" TARGET=_top>Conditionals</A></TD></TR><TR><TD><A HREF="balancing.html" TARGET=_top>Balancing Groups</A></TD></TR><TR><TD><A HREF="recurse.html" TARGET=_top>Recursion</A></TD></TR><TR><TD><A HREF="subroutine.html" TARGET=_top>Subroutines</A></TD></TR><TR><TD><A HREF="recurseinfinite.html" TARGET=_top>Infinite Recursion</A></TD></TR><TR><TD><A HREF="recurserepeat.html" TARGET=_top>Recursion &amp; Quantifiers</A></TD></TR><TR><TD><A HREF="recursecapture.html" TARGET=_top>Recursion &amp; Capturing</A></TD></TR><TR><TD><A HREF="recursebackref.html" TARGET=_top>Recursion &amp; Backreferences</A></TD></TR><TR><TD><A HREF="recursebacktrack.html" TARGET=_top>Recursion &amp; Backtracking</A></TD></TR><TR><TD><A HREF="posixbrackets.html" TARGET=_top>POSIX Bracket Expressions</A></TD></TR><TR><TD><A HREF="zerolength.html" TARGET=_top>Zero-Length Matches</A></TD></TR><TR><TD><A HREF="continue.html" TARGET=_top>Continuing Matches</A></TD></TR> </TABLE><TABLE CLASS=side CELLSPACING=0 CELLPADDING=4><TR><TD CLASS=sideheader>More on This Site</TD></TR><TR><TD><A HREF="index.html" TARGET=_top>Introduction</A></TD></TR><TR><TD><A HREF="quickstart.html" TARGET=_top>Regular Expressions Quick Start</A></TD></TR><TR><TD><A HREF="tutorial.html" TARGET=_top>Regular Expressions Tutorial</A></TD></TR><TR><TD><A HREF="replacetutorial.html" TARGET=_top>Replacement Strings Tutorial</A></TD></TR><TR><TD><A HREF="tools.html" TARGET=_top>Applications and Languages</A></TD></TR><TR><TD><A HREF="examples.html" TARGET=_top>Regular Expressions Examples</A></TD></TR><TR><TD><A HREF="refflavors.html" TARGET=_top>Regular Expressions Reference</A></TD></TR><TR><TD><A HREF="refreplace.html" TARGET=_top>Replacement Strings Reference</A></TD></TR><TR><TD><A HREF="books.html" TARGET=_top>Book Reviews</A></TD></TR><TR><TD><A HREF="print.html" TARGET=_top>Printable PDF</A></TD></TR><TR><TD><A HREF="about.html" TARGET=_top>About This Site</A></TD></TR><TR><TD><A HREF="updates.html" TARGET=_top>RSS Feed &amp; Blog</A></TD></TR></TABLE></DIV><div class=bodytext><div class=topad style="height:130px"><A HREF="https://www.regexbuddy.com/create.html" TARGET="_top"><picture><source media="(max-width: 370px)" srcset="ads/320/rxbtutorial100.png 1x, ads/320/rxbtutorial150.png 1.5x, ads/320/rxbtutorial200.png 2x, ads/320/rxbtutorial250.png 2.5x, ads/320/rxbtutorial300.png 3x, ads/320/rxbtutorial350.png 3.5x, ads/320/rxbtutorial400.png 4x"><source media="(max-width: 500px)" srcset="ads/360/rxbtutorial100.png 1x, ads/360/rxbtutorial150.png 1.5x, ads/360/rxbtutorial200.png 2x, ads/360/rxbtutorial250.png 2.5x, ads/360/rxbtutorial300.png 3x, ads/360/rxbtutorial350.png 3.5x, ads/360/rxbtutorial400.png 4x"><source media="(max-width: 660px)" srcset="ads/480/rxbtutorial100.png 1x, ads/480/rxbtutorial150.png 1.5x, ads/480/rxbtutorial200.png 2x, ads/480/rxbtutorial250.png 2.5x, ads/480/rxbtutorial300.png 3x, ads/480/rxbtutorial350.png 3.5x, ads/480/rxbtutorial400.png 4x"><source media="(max-width: 747px)" srcset="ads/640/rxbtutorial100.png 1x, ads/640/rxbtutorial150.png 1.5x, ads/640/rxbtutorial200.png 2x, ads/640/rxbtutorial250.png 2.5x, ads/640/rxbtutorial300.png 3x, ads/640/rxbtutorial350.png 3.5x, ads/640/rxbtutorial400.png 4x"><img src="ads/728/rxbtutorial100.png" srcset="ads/728/rxbtutorial100.png 1x, ads/728/rxbtutorial125.png 1.25x, ads/728/rxbtutorial150.png 1.5x, ads/728/rxbtutorial175.png 1.75x, ads/728/rxbtutorial200.png 2x, ads/728/rxbtutorial250.png 2.5x, ads/728/rxbtutorial300.png 3x, ads/728/rxbtutorial350.png 3.5x, ads/728/rxbtutorial400.png 4x" alt="RegexBuddy—Better than a regular expression tutorial!"></picture></A></div> <div class=bulb><h1>Testing The Same Part of a String for More Than One Requirement</h1><script type="text/javascript">showbulb();</script></div> <p><A HREF="lookaround.html" TARGET="_top">Lookaround</A>, which was introduced in detail in the <A HREF="lookaround.html" TARGET="_top">previous topic</A>, is a very powerful concept. Unfortunately, it is often underused by people new to regular expressions, because lookaround is a bit confusing. The confusing part is that the lookaround is zero-length. So if you have a regex in which a lookahead is followed by another piece of regex, or a lookbehind is preceded by another piece of regex, then the regex traverses part of the string twice.</p> <p>A more practical example makes this clear. Let’s say we want to find a word that is six letters long and contains the three consecutive letters <tt class=string>cat</tt>. Actually, we can match this without lookaround. We just specify all the options and lump them together using <A HREF="alternation.html" TARGET="_top">alternation</A>: <TT CLASS=syntax><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{3}</SPAN><SPAN CLASS="regexspecial">|</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{2}</SPAN><SPAN CLASS="regexspecial">|</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{2}</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">|</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{3}</SPAN><SPAN CLASS="regexplain">cat</SPAN></TT>. Easy enough. But this method gets unwieldy if you want to find any word between 6 and 12 letters long containing either “cat”, “dog” or “mouse”.</p> <h2>Lookaround to The Rescue</h2> <p>In this example, we basically have two requirements for a successful match. First, we want a word that is 6 letters long. Second, the word we found must contain the word “cat”.</p> <p>Matching a 6-letter word is easy with <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6}</SPAN><SPAN CLASS="regexspecial">\b</SPAN></TT>. Matching a word containing “cat” is equally easy: <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN><SPAN CLASS="regexspecial">\b</SPAN></TT>.</p> <p>Combining the two, we get: <TT CLASS=syntax><SPAN CLASS="regexnest1">(?=</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6}</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN><SPAN CLASS="regexspecial">\b</SPAN></TT>. Easy! Here’s how this works. At each character position in the string where the regex is attempted, the engine first attempts the regex inside the positive lookahead. This sub-regex, and therefore the lookahead, matches only when the current character position in the string is at the start of a 6-letter word in the string. If not, the lookahead fails and the engine continues trying the regex from the start at the next character position in the string.</p> <p>The lookahead is zero-length. So when the regex inside the lookahead has found the 6-letter word, the current position in the string is still at the beginning of the 6-letter word. The regex engine attempts the remainder of the regex at this position. Because we already know that a 6-letter word can be matched at the current position, we know that <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN></TT> matches and that the first <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT> matches 6 times. The engine then <A HREF="repeat.html" TARGET="_top">backtracks</A>, reducing the number of characters matched by <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>, until <TT CLASS=syntax><SPAN CLASS="regexplain">cat</SPAN></TT> can be matched. If <TT CLASS=syntax><SPAN CLASS="regexplain">cat</SPAN></TT> cannot be matched, the engine has no other choice but to restart at the beginning of the regex, at the next character position in the string. This is at the second letter in the 6-letter word we just found, where the lookahead will fail, causing the engine to advance character by character until the next 6-letter word.</p> <p>If <TT CLASS=syntax><SPAN CLASS="regexplain">cat</SPAN></TT> can be successfully matched, the second <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT> consumes the remaining letters, if any, in the 6-letter word. After that, the last <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN></TT> in the regex is guaranteed to match where the second <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN></TT> inside the lookahead matched. Our double-requirement-regex has matched successfully.</p> <h2>Optimizing Our Solution</h2> <p>While the above regex works just fine, it is not the most optimal solution. This is not a problem if you are just doing a search in a text editor. But optimizing things is a good idea if this regex will be used repeatedly and/or on large chunks of data in an application you are developing.</p> <p>You can discover these optimizations by yourself if you carefully examine the regex and follow how the regex engine applies it, as we did above. The third and last <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN></TT> are guaranteed to match. Since <A HREF="wordboundaries.html" TARGET="_top">word boundaries</A> are zero-length, and therefore do not change the result returned by the regex engine, we can remove them, leaving: <TT CLASS=syntax><SPAN CLASS="regexnest1">(?=</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6}</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>. Though the last <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT> is also guaranteed to match, we cannot remove it because it adds characters to the regex match. Remember that the lookahead discards its match, so it does not contribute to the match returned by the regex engine. If we omitted the <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>, the resulting match would be the start of a 6-letter word containing “cat”, up to and including “cat”, instead of the entire word.</p> <p>But we can optimize the first <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>. As it stands, it will match 6 letters and then backtrack. But we know that in a successful match, there can never be more than 3 letters before “cat”. So we can optimize this to <TT CLASS=code><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN></TT>. Note that making the asterisk lazy would not have optimized this sufficiently. The lazy asterisk would find a successful match sooner, but if a 6-letter word does not contain “cat”, it would still cause the regex engine to try matching “cat” at the last two letters, at the last single letter, and even at one character beyond the 6-letter word.</p> <p>So we have <TT CLASS=syntax><SPAN CLASS="regexnest1">(?=</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6}</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>. One last, minor, optimization involves the first <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN></TT>. Since it is zero-length itself, there’s no need to put it inside the lookahead. So the final regex is: <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">(?=</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6}</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>.</p> <p>You could replace the final <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT> with <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN></TT> too. But it wouldn’t make any difference. The lookahead has already checked that we’re at a 6-letter word, and <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN><SPAN CLASS="regexplain">cat</SPAN></TT> has already matched 3 to 6 letters of that word. Whether we end the regex with <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT> or <TT CLASS=syntax><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,3}</SPAN></TT> doesn’t matter, because either way, we’ll be matching all the remaining word characters. Because the resulting match and the speed at which it is found are the same, we may just as well use the version that is easier to type.</p> <h2>A More Complex Problem</h2> <p>So, what would you use to find any word between 6 and 12 letters long containing either “cat”, “dog” or “mouse”? Again we have two requirements, which we can easily combine using a lookahead: <TT CLASS=syntax><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">(?=</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{6,12}</SPAN><SPAN CLASS="regexspecial">\b</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">{0,9}</SPAN><SPAN CLASS="regexnest1">(</SPAN><SPAN CLASS="regexplain">cat</SPAN><SPAN CLASS="regexnest1">|</SPAN><SPAN CLASS="regexplain">dog</SPAN><SPAN CLASS="regexnest1">|</SPAN><SPAN CLASS="regexplain">mouse</SPAN><SPAN CLASS="regexnest1">)</SPAN><SPAN CLASS="regexspecial">\w</SPAN><SPAN CLASS="regexspecial">*</SPAN></TT>. Very easy, once you get the hang of it. This regex will also put “cat”, “dog” or “mouse” into the first backreference.</p><div id=cntmobi><p>|&ensp;<a href='quickstart.html'>Quick&nbsp;Start</a>&ensp;|&ensp;<a href='tutorial.html'>Tutorial</a>&ensp;|&ensp;<a href='tools.html'>Tools&nbsp;&amp;&nbsp;Languages</a>&ensp;|&ensp;<a href='examples.html'>Examples</a>&ensp;|&ensp;<a href='refflavors.html'>Reference</a>&ensp;|&ensp;<a href='books.html'>Book&nbsp;Reviews</a>&ensp;|</p><p>|&ensp;<a href='tutorial.html'>Introduction</a>&ensp;|&ensp;<a href='tutorialcnt.html'>Table of Contents</a>&ensp;|&ensp;<a href='characters.html'>Special Characters</a>&ensp;|&ensp;<a href='nonprint.html'>Non-Printable Characters</a>&ensp;|&ensp;<a href='engine.html'>Regex Engine Internals</a>&ensp;|&ensp;<a href='charclass.html'>Character Classes</a>&ensp;|&ensp;<a href='charclasssubtract.html'>Character Class Subtraction</a>&ensp;|&ensp;<a href='charclassintersect.html'>Character Class Intersection</a>&ensp;|&ensp;<a href='shorthand.html'>Shorthand Character Classes</a>&ensp;|&ensp;<a href='dot.html'>Dot</a>&ensp;|&ensp;<a href='anchors.html'>Anchors</a>&ensp;|&ensp;<a href='wordboundaries.html'>Word Boundaries</a>&ensp;|&ensp;<a href='alternation.html'>Alternation</a>&ensp;|&ensp;<a href='optional.html'>Optional Items</a>&ensp;|&ensp;<a href='repeat.html'>Repetition</a>&ensp;|&ensp;<a href='brackets.html'>Grouping &amp; Capturing</a>&ensp;|&ensp;<a href='backref.html'>Backreferences</a>&ensp;|&ensp;<a href='backref2.html'>Backreferences, part 2</a>&ensp;|&ensp;<a href='named.html'>Named Groups</a>&ensp;|&ensp;<a href='backrefrel.html'>Relative Backreferences</a>&ensp;|&ensp;<a href='branchreset.html'>Branch Reset Groups</a>&ensp;|&ensp;<a href='freespacing.html'>Free-Spacing &amp; Comments</a>&ensp;|&ensp;<a href='unicode.html'>Unicode</a>&ensp;|&ensp;<a href='modifiers.html'>Mode Modifiers</a>&ensp;|&ensp;<a href='atomic.html'>Atomic Grouping</a>&ensp;|&ensp;<a href='possessive.html'>Possessive Quantifiers</a>&ensp;|&ensp;<a href='lookaround.html'>Lookahead &amp; Lookbehind</a>&ensp;|&ensp;<a href='lookaround2.html'>Lookaround, part 2</a>&ensp;|&ensp;<a href='keep.html'>Keep Text out of The Match</a>&ensp;|&ensp;<a href='conditional.html'>Conditionals</a>&ensp;|&ensp;<a href='balancing.html'>Balancing Groups</a>&ensp;|&ensp;<a href='recurse.html'>Recursion</a>&ensp;|&ensp;<a href='subroutine.html'>Subroutines</a>&ensp;|&ensp;<a href='recurseinfinite.html'>Infinite Recursion</a>&ensp;|&ensp;<a href='recurserepeat.html'>Recursion &amp; Quantifiers</a>&ensp;|&ensp;<a href='recursecapture.html'>Recursion &amp; Capturing</a>&ensp;|&ensp;<a href='recursebackref.html'>Recursion &amp; Backreferences</a>&ensp;|&ensp;<a href='recursebacktrack.html'>Recursion &amp; Backtracking</a>&ensp;|&ensp;<a href='posixbrackets.html'>POSIX Bracket Expressions</a>&ensp;|&ensp;<a href='zerolength.html'>Zero-Length Matches</a>&ensp;|&ensp;<a href='continue.html'>Continuing Matches</a>&ensp;|</p></div> <div id=copyright> <P CLASS=copyright>Page URL: <A HREF="https://www.regular-expressions.info/lookaround2.html" TARGET="_top">https://www.regular-expressions.info/lookaround2.html</A><BR> Page last updated: 7 February 2024<BR> Site last updated: 06 November 2024<BR> Copyright &copy; 2003-2024 Jan Goyvaerts. All rights reserved.</P> </div> </div> </div> </body></html>

Pages: 1 2 3 4 5 6 7 8 9 10