regex 如何在Golang中删除字符串中多余的空格?

xv8emn3q  于 2022-12-14  发布在  Go
关注(0)|答案(7)|浏览(196)

我正琢磨着怎么去掉:

  • 所有前导/尾随空格或换行符、空字符等。
  • 字符串中的任何冗余空格(例如,“hello[space][space]world”将转换为“hello[space]world”)

这是否可能与一个单一的正则表达式,与国际空间字符的unicode支持等?

2vuwiymt

2vuwiymt1#

仅仅使用strings包就可以完成很多工作,因为strings.Fields为您完成了大部分工作:

package main

import (
    "fmt"
    "strings"
)

func standardizeSpaces(s string) string {
    return strings.Join(strings.Fields(s), " ")
}

func main() {
    tests := []string{" Hello,   World  ! ", "Hello,\tWorld ! ", " \t\n\t Hello,\tWorld\n!\n\t"}
    for _, test := range tests {
        fmt.Println(standardizeSpaces(test))
    }
}
// "Hello, World !"
// "Hello, World !"
// "Hello, World !"
iszxjhcz

iszxjhcz2#

看起来你可能想同时使用\s速记字符类和\p{Zs} Unicode属性来匹配Unicode空间。但是,这两个步骤不能用一个正则表达式替换来完成,因为你需要两个不同的替换,并且ReplaceAllStringFunc只允许整个匹配字符串作为参数(我不知道如何检查哪个组匹配)。
因此,我建议使用两个正则表达式:

  • ^[\s\p{Zs}]+|[\s\p{Zs}]+$-匹配所有前导/尾随空格
  • [\s\p{Zs}]{2,}-匹配字符串中的2个或多个空白符号

样本代码:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    input := "   Text   More here     "
    re_leadclose_whtsp := regexp.MustCompile(`^[\s\p{Zs}]+|[\s\p{Zs}]+$`)
    re_inside_whtsp := regexp.MustCompile(`[\s\p{Zs}]{2,}`)
    final := re_leadclose_whtsp.ReplaceAllString(input, "")
    final = re_inside_whtsp.ReplaceAllString(final, " ")
    fmt.Println(final)
}
wgeznvg7

wgeznvg73#

strings.Fields()在任意数量的白色上进行拆分,因此:

strings.Join(strings.Fields(strings.TrimSpace(s)), " ")
dffbzjpn

dffbzjpn4#

使用单个regexp,使用regexp.MustCompile()抓取所有空格,并将它们替换为单个空格,最后修剪前导空格。

package main

    import (
        "fmt"
        "regexp"
        "strings"
    )
    
    func main() {
        input := "    Text   More here        "
        re := regexp.MustCompile(`\s+`)
        out := re.ReplaceAllString(input, " ")
        out = strings.TrimSpace(out)
        fmt.Println(out)
    }

或者,使用“_”代替空格。

package main

import (
    "fmt"
    "regexp"
    "strings"
)

func main() {
    input := "___Text___More_here______"
    re := regexp.MustCompile(`_+`)
    out := re.ReplaceAllString(input, "_")
    out = strings.Trim(out, "_")
    fmt.Println(out)
}
hc2pp10m

hc2pp10m5#

避免使用浪费时间的regexp或外部库
我选择使用普通golang而不是regexp,因为在每种语言中都有一些特殊字符不是ASCII。
加油!

func RemoveDoubleWhiteSpace(str string) string {
    var b strings.Builder
    b.Grow(len(str))
    for i := range str {
        if !(str[i] == 32 && (i+1 < len(str) && str[i+1] == 32)) {
            b.WriteRune(rune(str[i]))
        }
    }
    return b.String()
}

及相关试验

func TestRemoveDoubleWhiteSpace(t *testing.T) {
    data := []string{`  test`, `test  `, `te  st`}
    for _, item := range data {
        str := RemoveDoubleWhiteSpace(item)
        t.Log("Data ->|"+item+"|Found: |"+str+"| Len: ", len(str))
        if len(str) != 5 {
            t.Fail()
        }
    }
}
nukf8bse

nukf8bse6#

// Ref: https://stackoverflow.com/a/42251527/18152508
func StrFields(input string) string {
    return strings.Join(strings.Fields(input), " ")
}

// Ref: https://stackoverflow.com/a/37293398/18152508
func RegexReplace(input string) string {
    re_leadclose_whtsp := regexp.MustCompile(`^[\s\p{Zs}]+|[\s\p{Zs}]+$`)
    re_inside_whtsp := regexp.MustCompile(`[\s\p{Zs}]{2,}`)

    return re_inside_whtsp.ReplaceAllString(
        re_leadclose_whtsp.ReplaceAllString(input, ""),
        " ",
    )
}

// Ref: https://stackoverflow.com/a/67152714/18152508
func SingleRegexp(input string) string {
    re := regexp.MustCompile(`\s+`)

    return strings.TrimSpace(re.ReplaceAllString(input, " "))
}

对上述3个函数进行基准测试,@ifross的method using strings.Fields function比公认的答案和使用正则表达式要快得多。
因此,我更喜欢strings.Fieldsstrings.Join的组合,只是为了减少字符串中冗余和重复的空格。
第一次

goqiplq2

goqiplq27#

请使用regexp执行此操作。

func main() {
    data := []byte("   Hello,   World !   ")
    re := regexp.MustCompile("  +")
    replaced := re.ReplaceAll(bytes.TrimSpace(data), []byte(" "))
    fmt.Println(string(replaced))
    // Hello, World !
}

为了同时修剪换行符和空字符,可以使用bytes.Trim(src []byte, cutset string)函数代替bytes.TrimSpace

相关问题