Go:如何检查字符串是否包含多个子字符串?

时间:2017-11-06 07:42:36

标签: string go

strings.Contains(str_to_check, substr)只需要一个参数作为要检查的子字符串,如何在不重复使用strings.Contains()的情况下检查多个子字符串?

例如。 strings.Contains(str_to_check, substr1, substr2)

4 个答案:

答案 0 :(得分:8)

您可以使用strings.Contains()编写自己的实用程序函数,该函数可以用于多个子字符串。

这是一个在完整/部分匹配和匹配总数的情况下返回布尔值(true / false)的示例:

package main

import (
    "fmt"
    "strings"
)

func checkSubstrings(str string, subs ...string) (bool, int) {

    matches := 0
    isCompleteMatch := true

    fmt.Printf("String: \"%s\", Substrings: %s\n", str, subs)

    for _, sub := range subs {
        if strings.Contains(str, sub) {
            matches += 1
        } else {
            isCompleteMatch = false
        }
    }

    return isCompleteMatch, matches
}

func main() {
    isCompleteMatch1, matches1 := checkSubstrings("Hello abc, xyz, abc", "abc", "xyz")
    fmt.Printf("Test 1: { isCompleteMatch: %t, Matches: %d }\n", isCompleteMatch1, matches1)

    fmt.Println()

    isCompleteMatch2, matches2 := checkSubstrings("Hello abc, abc", "abc", "xyz")
    fmt.Printf("Test 2: { isCompleteMatch: %t, Matches: %d }\n", isCompleteMatch2, matches2)
}

输出:

String: "Hello abc, xyz, abc", Substrings: [abc xyz]
Test 1: { isCompleteMatch: true, Matches: 2 }

String: "Hello abc, abc", Substrings: [abc xyz]
Test 2: { isCompleteMatch: false, Matches: 1 }

以下是实例:https://play.golang.org/p/Xka0KfBrRD

答案 1 :(得分:4)

是的,您可以在不多次调用strings.Contains()的情况下执行此操作。

如果您事先了解子字符串,则使用正则表达式检查此字符串的最简单方法。如果要检查的字符串很长并且您有相当多的子字符串,则可以更快地调用多个strings.Contains

示例https://play.golang.org/p/7PokxbOOo7

package main

import (
    "fmt"
    "regexp"
)

var re = regexp.MustCompile(`first|second|third`)

func main() {
    fmt.Println(re.MatchString("This is the first example"))
    fmt.Println(re.MatchString("This is the second example after first"))
    fmt.Println(re.MatchString("This is the third example"))
    fmt.Println(re.MatchString("This is the forth example"))
}

输出:

true
true
true
false

如果要检查的子项是动态的,那么创建正则表达式可能会有点困难,因为你需要转义特殊字符并且正则表达式编译不是很快,所以strings.Contains()在这种情况下可能更好,尽管如果它更好测试您的代码对性能至关重要。

另一个好的选择可能是编写自己的扫描程序,可以使用prefix tree在子字符串中使用公共前缀(,如果有的话)。

答案 2 :(得分:1)

另一种解决方案是使用regexpsuffixarray

的组合
package main

import (
    "fmt"
    "index/suffixarray"
    "regexp"
    "strings"
)

func main() {
    fmt.Println(contains("first secondthird", "first", "second", "third"))
    fmt.Println(contains("first secondthird", "first", "10th"))
}

func contains(str string, subStrs ...string) bool {
    if len(subStrs) == 0 {
        return true
    }
    r := regexp.MustCompile(strings.Join(subStrs, "|"))
    index := suffixarray.New([]byte(str))
    res := index.FindAllIndex(r, -1)
    exists := make(map[string]int)
    for _, v := range subStrs {
        exists[v] = 1
    }
    for _, pair := range res {
        s := str[pair[0]:pair[1]]
        exists[s] = exists[s] + 1
    }
    for _, v := range exists {
        if v == 1 {
            return false
        }
    }
    return true
}

(在Go Playground

答案 3 :(得分:0)

  

[H]我是否在不重复使用strings.Contains()的情况下检查多个子字符串?

完全没有。您重复调用包含。