Регистр строку поиска в golang

Как мне искать в файле слово в регистр способом?

Если я ищу UpdaTe в файле, если файл содержит обновление, поиск должен выбрать его и считать его совпадением.

4 ответов


strings.EqualFold() можно проверить, равны ли две строки, игнорируя регистр. Он даже работает с Unicode. См.http://golang.org/pkg/strings/#EqualFold для получения дополнительной информации.

http://play.golang.org/p/KDdIi8c3Ar

package main

import (
    "fmt"
    "strings"
)

func main() {
    fmt.Println(strings.EqualFold("HELLO", "hello"))
    fmt.Println(strings.EqualFold("ÑOÑO", "ñoño"))
}

оба возвращают true.


предположительно, важной частью вашего вопроса является поиск, а не часть о чтении из файла, поэтому я просто отвечу на эту часть.

вероятно, самый простой способ сделать это-преобразовать обе строки (ту, которую вы ищете, и ту, которую вы ищете) во весь верхний регистр или весь нижний регистр, а затем искать. Например:

func CaseInsensitiveContains(s, substr string) bool {
    s, substr = strings.ToUpper(s), strings.ToUpper(substr)
    return strings.Contains(s, substr)
}

вы можете увидеть его в действии здесь.


Если ваш файл большой, вы можете использовать regexp и bufio:

//create a regex `(?i)update` will match string contains "update" case insensitive
reg := regexp.MustCompile("(?i)update")
f, err := os.Open("test.txt")
if err != nil {
    log.Fatal(err)
}
defer f.Close()

//Do the match operation
//MatchReader function will scan entire file byte by byte until find the match
//use bufio here avoid load enter file into memory
println(reg.MatchReader(bufio.NewReader(f)))

о bufio

пакет bufio реализует буферизованный считыватель, который может быть полезен как для своей эффективности С много малых читает и из-за дополнительного методы чтения он обеспечивает.


не используйте strings.Contains Если вам не нужно точное соответствие, а не язык-Правильный поиск строк

ни один из текущих ответов не является правильным, если вы только не ищете символы ASCII меньшинство языков (например, английский) без определенных diaeresis / umlauts или других модификаторов символов Юникода (более "правильный" способ определить его, как указано в @snap). Стандартная фраза google - " поиск без ASCII письмена."

для правильной поддержки поиска языка вам нужно использовать http://golang.org/x/text/search.

func SearchForString(str string, substr string) (int, int) {
    m := search.New(language.English, search.IgnoreCase)
    return = m.IndexString(str, substr)
}

start, end := SearchForString('foobar', 'bar');
if start != -1 && end != -1 {
    fmt.Println("found at", start, end);
}

или если вы просто хотите начальный индекс:

func SearchForStringIndex(str string, substr string) (int, bool) {
    m := search.New(language.English, search.IgnoreCase)
    start, _ := m.IndexString(str, substr)
    if start == -1 {
        return 0, false
    }
    return start, true
}

index, found := SearchForStringIndex('foobar', 'bar');
if found {
    fmt.Println("match starts at", index);
}

Поиск language.Tag структуры здесь найти язык, который вы хотите найти или использовать language.Und если вы не уверены.

обновление

кажется, есть некоторая путаница, поэтому этот следующий пример должен помочь прояснить вещи.

package main

import (
    "fmt"
    "strings"

    "golang.org/x/text/language"
    "golang.org/x/text/search"
)

var s = `Æ`
var s2 = `Ä`

func main() {
    m := search.New(language.Finnish, search.IgnoreDiacritics)
    fmt.Println(m.IndexString(s, s2))
    fmt.Println(CaseInsensitiveContains(s, s2))
}

// CaseInsensitiveContains in string
func CaseInsensitiveContains(s, substr string) bool {
    s, substr = strings.ToUpper(s), strings.ToUpper(substr)
    return strings.Contains(s, substr)
}