Wie mache ich in Go einen regulären Ausdruck ohne Berücksichtigung der Groß- und Kleinschreibung?

83

Jetzt könnte ich natürlich meinen regulären Ausdruck schreiben, um beide Fälle zu behandeln, wie z. B. regexp.Compile("[a-zA-Z]"), aber mein regulärer Ausdruck besteht aus einer vom Benutzer angegebenen Zeichenfolge:

reg, err := regexp.Compile(strings.Replace(s.Name, " ", "[ \\._-]", -1))

Wo s.Nameist der Name? Das könnte so etwas wie "North by Northwest" sein. Die naheliegendste Lösung für mich wäre, durch jedes Zeichen zu gehen s.Nameund für jeden Buchstaben '[nN]' zu schreiben:

for i := 0; i < len(s.Name); i++ {
  if s.Name[i] == " " {
    fmt.Fprintf(str, "%s[ \\._-]", str);
  } else {
    fmt.Fprintf(str, "%s[%s%s]", str, strings.ToLower(s.Name[i]), strings.ToUpper(s.Name[i]))
  }
}

Ich halte dies jedoch für eine eher nicht elegante Lösung. Geschwindigkeit ist nicht wirklich ein Problem, aber ich muss wissen, ob es einen anderen Weg gibt.

Svip
quelle

Antworten:

167

Sie können ein Flag ohne Berücksichtigung der Groß- und Kleinschreibung als erstes Element in der Regex festlegen.

Sie tun dies, indem Sie "(?i)"am Anfang eines regulären Ausdrucks hinzufügen .

reg, err := regexp.Compile("(?i)"+strings.Replace(s.Name, " ", "[ \\._-]", -1))

Für eine feste Regex würde es so aussehen.

r := regexp.MustCompile(`(?i)CaSe`)

Weitere Informationen zu Flags finden Sie in der regexp/syntaxPaketdokumentation (oder in der Syntaxdokumentation ) nach dem Begriff "Flags".

Daniel
quelle
4
Aber ich fand das zu langsam, wenn es viele Daten gibt. Aufgrund des Aufrufs von unicode.SimpleFold in regexp.Match empfehle ich daher, die Buchstaben in obere Buchstaben zu ändern und dann regexp zu verwenden, um eine Übereinstimmung zu erzielen. Das ist Geschwindigkeit. Das Folgende sind Zeitdaten: `` `#By (? I) regexp, um den Fall XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / Frameworks -f Code / Frameworks 1271.94s Benutzer 7.32s System 97% CPU zu ignorieren 21: 54.95 gesamt #By toUpper und Match XCMP / bin / otacmp -o BSP_2.2.0.html -f BSP / Frameworks -f Code / Frameworks 263.87s Benutzer 8.99s System 110% CPU 4: 06.44 gesamt `` `
QJGui
1
Es sieht so aus, als ob eine langsame Leistung bei regulärem Regexp ohne Berücksichtigung der Groß- und Kleinschreibung ein bekannter Fehler war, der in den folgenden Monaten behoben wurde: github.com/golang/go/issues/13288
Dan Esparza
25

Sie können (?i)am Anfang des Musters ein hinzufügen , um die Groß- und Kleinschreibung nicht zu berücksichtigen.

Referenz

Qtax
quelle
4

Verwenden Sie die iFlagge. Unter Angabe der Spitze Dokumentation :

Gruppierung:

(re)           numbered capturing group
(?P<name>re)   named & numbered capturing group
(?:re)         non-capturing group
(?flags)       set flags within current group; non-capturing
(?flags:re)    set flags during re; non-capturing

Die Flaggensyntax lautet xyz (set) oder -xyz (clear) oder xy-z (set xy, clear z). Die Flaggen sind:

i              case-insensitive (default false)
m              multi-line mode: ^ and $ match begin/end line in addition to begin/end text (default false)
s              let . match \n (default false)
U              ungreedy: swap meaning of x* and x*?, x+ and x+?, etc (default false)
zzzz
quelle
22
Wo im Code soll ich diese i, m, s und U setzen?
Qian Chen
25
Diese Antwort ist ebenso wenig hilfreich wie die Dokumentation. Zum Glück gibt es unten ein funktionierendes Beispiel.
Laurent