Lookahead and Lookbehind regex
Sometimes we need to look if a string matches or contains a certain pattern and that's what regular expressions (regex) are for.
But sometimes we have the condition that this pattern is preceded or followed by another certain pattern.
We certainly can do that as easy as adding this other pattern to the one we are looking for
Pattern looked for: [0-9]*
Preceded by: [a-z]
Join and profit: [a-z][0-9]*
But what happens if we need this condition to be matched but we want to get the string that matched the pattern without the conditioning pattern
a = "k47"
# match all numbers preceded by a letter
a.match(/[a-z][0-9]*/)[0]
# but we just want the number :(
> "k47"
Introducing lookahead and lookbehind regex
lookahead
(?=regex)
Meaning: followed by the expression regex
but without including it in the match
ej.
a yolo followed by a lo but without including it in the match
http://rubular.com/?regex=yolo(?=lo)&test=yolo%20yololo
input: yolo yololo
regex: yolo(?=lo)
result: yolo yololo
(?!regex)
Meaning: not followed by the expression regex
ej.
a yolo not followed by a lo
http://rubular.com/?regex=yolo(?!lo)&test=yolo%20yololo
input: yolo yololo
regex: yolo(?!lo)
result: yolo yololo
lookbehind
(?<=regex)
Meaning: preceded by the expression regex
but without including it in the match
ej.
a lol preceded by a yo but without including it in the match
http://rubular.com/?regex=(?%3C=yo)lol&test=lol%20yololo
input: lol yololo
regex: (?<=yo)lol
result: lol yololo
(?<!regex)
Meaning: not preceded by the expression regex
ej.
a lol not preceded by a yo
http://rubular.com/?regex=(?%3C!yo)lol&test=lol%20yololo
input: lol yololo
regex: (?<!yo)lol
result: lol yololo
Ruby example
a.gsub(/(?<=:)[0-9]+/, '"\0"')
Surround any number preceded by a :
between "
a = "{a:123,c:12345}"
a.gsub(/(?<=:)[0-9]+/, '"\0"')
> "{a:\"123\",c:\"12345\"}"
the regex syntax can change depending on the language