## Escaping function
regex.escape <- function(string) {
gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
fun <- function(text, search) {
gsub(paste0("(?!\\B\\w)(", regex.escape(search), ")(?<!\\w\\B)"), "<mark>\\1</mark>",
text, ignore.case = TRUE, perl=TRUE)
}
fun("this is a test.", ".")
# [1] "this is a test<mark>.</mark>"
fun("(this is a test)", ")")
# [1] "(this is a test<mark>)</mark>"
IyMgRXNjYXBpbmcgZnVuY3Rpb24KcmVnZXguZXNjYXBlIDwtIGZ1bmN0aW9uKHN0cmluZykgewogIGdzdWIoIihbXVt7fSgpKypeJHxcXFxcPy5dKSIsICJcXFxcXFwxIiwgc3RyaW5nKQp9CmZ1biA8LSBmdW5jdGlvbih0ZXh0LCBzZWFyY2gpIHsKICBnc3ViKHBhc3RlMCgiKD8hXFxCXFx3KSgiLCByZWdleC5lc2NhcGUoc2VhcmNoKSwgIikoPzwhXFx3XFxCKSIpLCAiPG1hcms+XFwxPC9tYXJrPiIsCiAgICAgICB0ZXh0LCBpZ25vcmUuY2FzZSA9IFRSVUUsIHBlcmw9VFJVRSkKfQpmdW4oInRoaXMgaXMgYSB0ZXN0LiIsICIuIikKIyBbMV0gInRoaXMgaXMgYSB0ZXN0PG1hcms+LjwvbWFyaz4iCgpmdW4oIih0aGlzIGlzIGEgdGVzdCkiLCAiKSIpCiMgWzFdICIodGhpcyBpcyBhIHRlc3Q8bWFyaz4pPC9tYXJrPiI=