如何检查文本文件中是否包含整个单词?

时间:2019-04-22 17:46:54

标签: go

我正在尝试检查文本文件是否包含某个单词。但是,即使字符串中的某些字母也会返回true。例如:

输入的字符串:gdo

找到计算机:kin gdo m

var word = strings.ToLower(string(a))

// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
    panic(err)
}
s := string(b)

// Check whether s contains substring text
if strings.Contains(s, word) == true {
    fmt.Println("this is a word ", word)
} else {
    fmt.Println("this isn't a word ", word)
}

3 个答案:

答案 0 :(得分:0)

strings.Contains()报告字符串中是否包含子字符串。它不会检查单词边界,因此您所期望的行为是可以预期的。

您想要的是将每个单词识别为一个单词。已经有strings.Fields()函数可以通过空格分割文本。一个简单的实现可能看起来像:

func main() {
    source := `
hello
world
kingdom
foo
`
    check := "gdo"
    words := strings.Fields(strings.ToLower(source))

    for _, w := range words {
        if w == check {
            fmt.Println("found", check)
            break
        }
    }
}

我使用strings.Fields()是因为我不知道您的words.txt文件的内容。如果您知道分隔符始终是单个换行符或单个空格,则也可以使用strings.Split()

如果您要进行大量查找,这将很慢,因为它会为每个查找循环遍历words数组。一种更快的方法是将其存储在地图中:

func main() {
    source := `
hello
world
kingdom
foo
`
    check := "gdo"

    words := make(map[string]struct{})
    for _, w := range strings.Fields(strings.ToLower(source)) {
        words[w] = struct{}{}
    }

    _, ok := words[check]
    if ok {
        fmt.Println("found", check)
    }
}

如果仅执行一次查找,则第一种方法会更快(因为此map方法将始终需要至少循环一次整个数组才能构建地图)。

我使用了看起来有些奇怪的空结构作为映射值,因为它不会分配任何内存(words[w] = true会分配)。

答案 1 :(得分:0)

这是一个简单的解决方案。您可以将s转换为字符串数组。然后遍历数组以检查它是否包含单词。

var word = strings.ToLower(string(a))

// read the whole file at once
b, err := ioutil.ReadFile("words.txt")
if err != nil {
    panic(err)
}
s := string(b)

// convert the string into a string array (words)

content := strings.Split(s, " ")

contains := false

for i:=0 ; i<len(content) ; i++ {
    if content[i] == word {
        contains = true
        break
    }
}

// Check whether s contains substring text
if contains {
    fmt.Println("this is a word ", word)
} else {
    fmt.Println("this isn't a word ", word)
}

无需复杂化。祝你有美好的一天:)

答案 2 :(得分:0)

如果不区分大小写,则可以使用opened a ticket包中的suffixArray。

 b, err := ioutil.ReadFile("words.txt")
 if err != nil {
    panic(err)
 }
 
 word := "gdo"
 suffix := suffixarray.New(b) // accepts []byte
 indexList := suffix.Lookup([]byte(word), -1)
 if len(indexList) == 0 {
    fmt.Println("this isn't a word ", word)
    return
 }

 s := string(b)
 // loop through the word indices
 for _, idx := range indexList {
    fmt.Println("this is a word ", string(s[idx:idx+len(word)]))
 }