web-dev-qa-db-fra.com

Recherche de chaîne insensible à la casse dans Golang

Comment rechercher un mot dans un fichier d'une manière insensible à la casse ?

Par exemple

Si je recherche UpdaTe dans le fichier, si le fichier contient une mise à jour, la recherche doit le choisir et le compter comme une correspondance.

25
user3841581

strings.EqualFold() peut vérifier si deux chaînes sont égales, tout en ignorant la casse. Cela fonctionne même avec Unicode. Voir http://golang.org/pkg/strings/#EqualFold pour plus d'informations.

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"))
}

Les deux retournent vrai.

59
425nesp

Vraisemblablement, la partie importante de votre question est la recherche, pas la partie sur la lecture d'un fichier, donc je vais juste répondre à cette partie.

La façon la plus simple de le faire est probablement de convertir les deux chaînes (celle que vous recherchez et celle que vous recherchez) en majuscules ou en minuscules, puis de rechercher. Par exemple:

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

Vous pouvez le voir en action ici .

13
joshlf

Ne pas utiliser strings.Contains sauf si vous avez besoin d'une correspondance exacte plutôt que de recherches de chaînes de caractères correctes

Aucune des réponses actuelles n'est correcte, sauf si vous recherchez uniquement Caractères ASCII  la minorité de langues (comme l'anglais) sans certains tréma/trémas ou autres modificateurs de glyphe unicode (la façon la plus "correcte" de le définir comme mentionné par @ casser). La phrase google standard est "recherche de caractères non ASCII".

Pour une prise en charge appropriée de la recherche de langue, vous devez utiliser 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);
}

Ou si vous voulez juste l'index de départ:

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);
}

Cherche le language.Tag structs here pour trouver la langue que vous souhaitez rechercher ou utiliser language.Und si vous n'êtes pas sûr.

Mise à jour

Il semble y avoir une certaine confusion, donc cet exemple suivant devrait aider à clarifier les choses.

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)
}
6
Xeoncross

Si votre fichier est volumineux, vous pouvez utiliser regexp et 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)))

À propos de bufio

Le paquet bufio implémente un lecteur tamponné qui peut être utile à la fois pour son efficacité avec de nombreuses petites lectures et en raison des méthodes de lecture supplémentaires qu'il fournit.

6
chendesheng