Wie kann ich überprüfen, ob eine Zeichenfolge in C ++ Sonderzeichen enthält?

7

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.

    
Praveen 07.07.2011, 02:46
quelle

8 Antworten

11

Versuchen Sie:

%Vor%

Oder boosten Sie reguläre Ausdrücke:

%Vor%     
Martin York 07.07.2011, 02:50
quelle
3

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.

Ссылка

  • Iteriere durch jedes Zeichen
  • Überprüfen Sie, ob das Zeichen der Dezimalwert 48 - 57, 65 - 90, 97 - 122 oder 95 (Unterstrich)
  • ist
feathj 07.07.2011 02:59
quelle
3

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:

%Vor%

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).

    
Adam Rosenfield 07.07.2011 02:58
quelle
2

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:

%Vor%

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:

%Vor%

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.

    
Jerry Coffin 07.07.2011 05:57
quelle
1

Die Funktionen (Makros) unterliegen Gebietsschemaeinstellungen, aber Sie sollten isalnum() und Verwandte aus <ctype.h> oder <cctype> untersuchen.

    
Jonathan Leffler 07.07.2011 02:51
quelle
0

Ich würde hier einfach die eingebaute C-Einrichtung benutzen. Iteriere über jedes Zeichen in der Zeichenfolge und überprüfe, ob es _ ist oder ob isalpha(ch) wahr ist. Wenn ja, dann ist es gültig, sonst ist es ein Sonderzeichen.

    
Mark B 07.07.2011 02:56
quelle
0

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%     

Tony Delroy 07.07.2011 03:10
quelle
0

Verwenden Sie

%Vor% Mit

erhalten Sie eine saubere Zeichenfolge s .

Erase löscht alle Sonderzeichen und ist sehr anpassbar mit der Funktion my_predicate .

    
Bhavya Agarwal 23.09.2012 07:59
quelle

Tags und Links