Как выполнить поиск в файле для слова без учета регистра?
Например
Если я ищу UpdaTe
в файле, если файл содержит обновление, поиск должен выбрать его и считать в качестве соответствия.
Как выполнить поиск в файле для слова без учета регистра?
Например
Если я ищу UpdaTe
в файле, если файл содержит обновление, поиск должен выбрать его и считать в качестве соответствия.
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 реализован буферный считыватель, который может быть полезен как за его эффективность с большим количеством мелких чтений и из-за дополнительного которые он предоставляет.
strings.Contains
, если вам не нужны точные соответствия, а не правильные строки поиска по строкеНи один из текущих ответов не является правильным, если вы не только ищете ASCII-символы меньшинство языков (например, английский) без определенных diaeresis/умляутов или других модификаторов глифов Unicode (чем больше "правильный" способ определите его, как указано @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
structs here, чтобы найти язык, который вы хотите найти, или используйте 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)
}