The question of the day is how to use a regular expression to select the last instance of a word in a string of text. Finding the first instance is quite straightforward, but finding the last isn’t as intuitive.
So how’s it done?
The answer lies in a feature of the regular expression engine called Negative Lookahead.
Negative Lookahead is a regular expression lookaround function that belongs to a grouop of functions that do not select matching text. A negative lookahead lets you match a pattern that is then not followed by another pattern.
Let’s say we have an example string with several repeating instances of the text abc:
If we want to match the last instance of the string abc, then we can use a negative lookahead that looks for the text abc, and that is not followed by any further abc text. In a regular expression this is written as:
In this expression, the first abc is the pattern to match. Since there are many instances of abc in our example text, we will need a negative lookahead to help us only find the last instance of abc… in other words, the instance of abc where there are no following instances of abc. This is done using wildcard text matching: .* followed by the string abc.
As you can see, this is a straightforward and effective regular expression to match the last occurrence of a string of text.
In a more practical example, let’s say we have an HTML text input area on our Web page as follows:
<input type="text" id="myText" value="the fox once said hello to the fox in the glen">
var myTextValue = document.getElementById('myText').value; var strOutText = 'initial: ' + myTextValue + '\r\n'; var strModText = strOutText.replace(/fox(?!.*fox)/, 'hawk'); strOutText += 'modified: ' +strModText; alert(strOutText);
Example in TypeScript
Here is the HTML:
<input type="text" id="myText" value="the fox once said hello to the fox in the glen" style="width:300px;"> <br> <input type="text" id="myTextOut" value="" style="width:300px;">
Here is the TypeScript version of the example:
var myTextValue: string = document.getElementById('myText').value; var strOutText: string = myTextValue + '\r\n'; var strModText: string = strOutText.replace(/fox(?!.*fox)/, 'hawk'); strOutText += 'modified: ' +strModText; document.getElementById('myTextOut').value = strModText;