There are several problems here:
- An unescaped
.
matches any char other than line break, it must be escaped. Since you are building the pattern dynamically, use regexp.QuoteMeta
- As a
\b
word boundary after .
requires a word char, you can't expect a\.\b
to match a. b
. Replace the boundaries with (^|[^\p{L}0-9_])
for the leading boundary and ([^\p{L}0-9_]|$)
for the trailing boundary.
- At this stage, the pattern will be built like this:
`(?i)(^|[^\p{L}0-9_])`+regexp.QuoteMeta(search)+`([^\p{L}0-9_]|$)`
, but since both the boundaries are consuming patterns, you will never match consecutive matches (corp. corp.
will result in Corporation corp.
, the second one won't be replaced). You should repeat replacing until no regex match can be found.
- And to make the pattern case insensitive, use
(?i)
inline modifier at the pattern start.
The regex will look like
(?i)(^|[^\p{L}0-9_])corp\.([^\p{L}0-9_]|$)
See the regex demo.
Details
-
(?i)
- case insensitive modifier
-
(^|[^\p{L}0-9_])
- either start of string or a char other than a Unicode letter, ASCII digit and _
-
corp\.
- a corp.
substring
-
([^\p{L}0-9_]|$)
- either a char other than a Unicode letter, ASCII digit and _
or end of string
See this example demo:
package main
import (
"fmt"
"regexp"
)
func main() {
search :="corp."
rep := "Corporation"
sample :="SS Corp. Corp. LTd"
var re = regexp.MustCompile(`(?i)(^|[^\p{L}0-9_])`+regexp.QuoteMeta(search)+`([^\p{L}0-9_]|$)`)
fmt.Println(re)
var res = sample
for re.MatchString(res) {
res = ReplaceWith(res, re, "${1}"+rep+"${2}")
}
fmt.Println(res)
}
func ReplaceWith(s string, re *regexp.Regexp, repl string) string {
return re.ReplaceAllString(s, repl)
}
Result: SS Corporation Corporation LTd
.