You need to pass the (?m)
inline modifier:
regexp.MustCompile(`(?m)^\s*$`)
^^^^
The MULTILINE modifier will make ^
match the start of the line and $
will match the end of a line:
m
multi-line mode: ^
and $
match begin/end line in addition to begin/end text (default false)
Another thing to bear in mind is that \s
matches [\t
\f ]
symbols. If you want to match all horizontal whitespaces, you may use [ \t]
or [\t\p{Zs}]
. That will let you stay inside the line bounds.
And another thing: $
only asserts the position after a line break, it does not consume it, so, you need to actually match
or
or
after $
(if you need to remove the linebreaks, too).
This is what I came up with (demo):
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile(`(?m)^\s*$[
]*|[
]+\s+\z`)
in := `
test
test
`
want_empty := ` test
test `
fmt.Printf("have [%v]
", in)
fmt.Printf("want [%v]
", want_empty)
fmt.Printf("got [%v]
", re.ReplaceAllString(in, ""))
}
The ^\s*$[
]*
- matches the start of a line, any 0+ whitespaces, assets the end of a line ($
) and then matches 0+ LF/CR symbols.
The [
]+\s+\z
alternative matches 1 or more CR or LF symbols, 1+ whitespaces and then the unambiguous end of string \z
, without it, ^\s*$[
]*
won't match the last empty line.