Ich versuche herauszufinden, ob es eine bessere Möglichkeit gibt zu überprüfen, ob die Zeichenfolge Sonderzeichen enthält. In meinem Fall wird alles andere als alphanumerisch und ein '_' als Sonderzeichen betrachtet. Momentan habe ich eine Zeichenfolge, die Sonderzeichen wie std :: string="! @ # $% ^ & Amp;" enthält. Ich verwende dann den std :: find_first_of () - Algorithmus, um zu überprüfen, ob eines der Sonderzeichen in der Zeichenfolge vorhanden ist.
Ich habe mich gefragt, wie ich das auf Basis von Whitelisting machen soll. Ich möchte die Klein- / Großbuchstaben, Zahlen und einen Unterstrich in einer Zeichenfolge angeben (ich möchte sie nicht auflisten. Gibt es eine Möglichkeit, den Ascii-Bereich einer Art wie [a-zA-Z0-9_] anzugeben ). Wie kann ich das erreichen? Dann plane ich, das std :: find_first_not_of () zu verwenden. Auf diese Weise kann ich erwähnen, was ich eigentlich will und nach dem Gegenteil suchen.
Versuchen Sie:
%Vor%Oder boosten Sie reguläre Ausdrücke:
%Vor%Das erste, was Sie beachten müssen, ist "Ist das nur ASCII"? Wenn Sie ja antworten, würde ich Sie ermutigen, wirklich zu überlegen, ob Sie nur ASCII zulassen sollten. Ich arbeite derzeit für eine Firma, die wirklich Probleme hat, in ausländische Märkte zu kommen, weil wir nicht daran gedacht haben, Unicode von Anfang an zu unterstützen.
Damit lässt sich ASCII sehr einfach auf Nicht-Alpha-Zahlen überprüfen. Sehen Sie sich das ASCII-Diagramm an.
Es gibt keine Möglichkeit, Standard C oder C ++ zu verwenden, um Zeichenbereiche zu verwenden. Sie müssen alle Zeichen auflisten. Für C-Strings können Sie strspn(3)
und strcspn(3)
, um das erste Zeichen in einer Zeichenfolge zu finden, die Mitglied eines bestimmten Zeichensatzes ist oder nicht Mitglied ist. Zum Beispiel:
Für C ++ - Zeichenfolgen können Sie die Elementfunktionen find_first_of
und find_first_not_of
gleichwertig verwenden.
Eine andere Möglichkeit ist die Verwendung der isalnum(3)
und verwandten Funktionen von <ctype.h>
, um zu testen, ob a gegebenes Zeichen ist alphanumerisch oder nicht; Beachten Sie, dass diese Funktionen länderabhängig sind , sodass sich ihr Verhalten in anderen Ländereinstellungen ändern kann. Wenn Sie dieses Verhalten nicht möchten, verwenden Sie sie nicht. Wenn Sie sich entscheiden, diese zu verwenden, müssen Sie auch separat nach Unterstrichen suchen, da es keine Funktion gibt, die "alphabetisch, numerisch oder Unterstrich" testet, und Sie müssen auch Ihre eigene Schleife codieren, um die Zeichenfolge zu suchen ( oder verwende std::find
mit einem geeigneten Funktionsobjekt).
Ich denke, ich würde den Job ein wenig anders machen, indem ich std::string
als Sammlung behandle und einen Algorithmus verwende. Mit einem C ++ 0x Lambda würde es ungefähr so aussehen:
Zumindest wenn du mit char
(nicht wchar_t
) klarkommst, wird isalnum
normalerweise einen Tabellen-Lookup verwenden, also ist es normalerweise (ein bisschen) schneller als alles was auf% co_de basiert % (wird normalerweise eine lineare Suche verwenden). IOW, das ist O (N) (N = str.size ()), wobei etwas, das auf find_first_of
basiert, O (N * M) ist, (N = str.size (), M = pattern.size () ).
Wenn Sie den Job mit reinem C ausführen möchten, können Sie find_first_of
mit einer Scanset-Konvertierung verwenden, die theoretisch nicht portierbar ist, aber im Wesentlichen von allen aktuellen / populären Compilern unterstützt wird:
Die Grundidee hier ist ziemlich einfach: das Scanset überspringt alle aufeinanderfolgenden nicht-speziellen Zeichen (aber das Ergebnis wird wegen des scanf
nicht zugewiesen), dann versuchen wir, ein weiteres Zeichen zu lesen. Wenn das gelingt, bedeutet das, dass mindestens ein Zeichen nicht übersprungen wurde, also müssen wir mindestens ein Sonderzeichen haben. Wenn dies fehlschlägt, bedeutet dies, dass die Konvertierung des Scansets mit der gesamten Zeichenfolge übereinstimmte, sodass alle Zeichen "nicht speziell" waren.
Offiziell besagt der C-Standard, dass der Versuch, einen Bereich in eine Scanset-Konvertierung zu setzen, nicht übertragbar ist (ein "-" irgendwo anders als der Anfang oder das Ende des Scansets gibt ein implementierungsdefiniertes Verhalten). Es gab sogar ein paar Compiler (aus Borland), die das scheitern würden - sie würden *
als genau die drei möglichen Zeichen 'A', '-' und 'Z' behandeln. Die meisten aktuellen Compiler (oder, genauer gesagt, Standard-Bibliotheksimplementierungen) gehen von dem folgenden Ansatz aus: "A-Z" entspricht jedem Großbuchstaben.
Die Funktionen (Makros) unterliegen Gebietsschemaeinstellungen, aber Sie sollten isalnum()
und Verwandte aus <ctype.h>
oder <cctype>
untersuchen.
Wenn Sie das wollen, aber nicht das ganze Schwein gehen und regexps verwenden wollen, und vorausgesetzt, Sie testen für ASCII-Zeichen - erstellen Sie einfach eine Funktion, um die Zeichenfolge für find_first_not_of
... zu generieren. p>
%Vor%
Verwenden Sie
%Vor% Mit erhalten Sie eine saubere Zeichenfolge s
.
Erase löscht alle Sonderzeichen und ist sehr anpassbar
mit der Funktion my_predicate
.