Ich stelle mir vor, ich muss die Zeichen 0-31 und 127 entfernen.
Gibt es eine Funktion oder einen Code, um dies effizient zu tun?
Wenn Ihre Tardis gerade 1963 gelandet ist und Sie nur die 7-Bit-druckbaren ASCII-Zeichen möchten, können Sie Folgendes von 0-31 und 127-255 herausreißen:
$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);
Es stimmt mit allem in den Bereichen 0-31, 127-255 überein und entfernt es.
Sie sind in eine Whirlpool-Zeitmaschine gefallen und in den achtziger Jahren zurück. Wenn Sie eine Form von 8-Bit-ASCII haben, möchten Sie möglicherweise die Zeichen im Bereich von 128 bis 255 halten. Eine einfache Einstellung - suchen Sie einfach nach 0-31 und 127
$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);
Ah, willkommen zurück im 21. Jahrhundert. Wenn Sie eine UTF-8-codierte Zeichenfolge haben, kann der /u
Modifikator für die Regex verwendet werden
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);
Dadurch werden nur 0-31 und 127 entfernt. Dies funktioniert in ASCII und UTF-8, da beide denselben Kontrollsatzbereich verwenden (wie von mgutt unten angegeben). Genau genommen würde dies ohne den /u
Modifikator funktionieren . Aber es macht das Leben leichter, wenn Sie andere Zeichen entfernen möchten ...
Wenn Sie mit Unicode arbeiten, gibt es möglicherweise viele nicht druckbare Elemente . Betrachten wir jedoch ein einfaches: NO-BREAK SPACE (U + 00A0)
In einer UTF-8-Zeichenfolge würde dies als codiert 0xC2A0
. Sie können diese bestimmte Sequenz suchen und entfernen, aber mit dem /u
Modifikator können Sie einfach \xA0
die Zeichenklasse hinzufügen :
$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);
preg_replace ist ziemlich effizient, aber wenn Sie diesen Vorgang häufig ausführen, können Sie ein Array von Zeichen erstellen, die Sie entfernen möchten, und str_replace verwenden, wie von mgutt unten angegeben, z
//build an array we can re-use across several operations
$badchar=array(
// control characters
chr(0), chr(1), chr(2), chr(3), chr(4), chr(5), chr(6), chr(7), chr(8), chr(9), chr(10),
chr(11), chr(12), chr(13), chr(14), chr(15), chr(16), chr(17), chr(18), chr(19), chr(20),
chr(21), chr(22), chr(23), chr(24), chr(25), chr(26), chr(27), chr(28), chr(29), chr(30),
chr(31),
// non-printing characters
chr(127)
);
//replace the unwanted chars
$str2 = str_replace($badchar, '', $str);
Intuitiv scheint dies schnell zu sein, aber es ist nicht immer der Fall. Sie sollten auf jeden Fall einen Benchmark erstellen, um zu sehen, ob Sie dadurch etwas sparen. Ich habe einige Benchmarks über eine Vielzahl von Stringlängen mit zufälligen Daten durchgeführt, und dieses Muster wurde mit PHP 7.0.12 erstellt
2 chars str_replace 5.3439ms preg_replace 2.9919ms preg_replace is 44.01% faster
4 chars str_replace 6.0701ms preg_replace 1.4119ms preg_replace is 76.74% faster
8 chars str_replace 5.8119ms preg_replace 2.0721ms preg_replace is 64.35% faster
16 chars str_replace 6.0401ms preg_replace 2.1980ms preg_replace is 63.61% faster
32 chars str_replace 6.0320ms preg_replace 2.6770ms preg_replace is 55.62% faster
64 chars str_replace 7.4198ms preg_replace 4.4160ms preg_replace is 40.48% faster
128 chars str_replace 12.7239ms preg_replace 7.5412ms preg_replace is 40.73% faster
256 chars str_replace 19.8820ms preg_replace 17.1330ms preg_replace is 13.83% faster
512 chars str_replace 34.3399ms preg_replace 34.0221ms preg_replace is 0.93% faster
1024 chars str_replace 57.1141ms preg_replace 67.0300ms str_replace is 14.79% faster
2048 chars str_replace 94.7111ms preg_replace 123.3189ms str_replace is 23.20% faster
4096 chars str_replace 227.7029ms preg_replace 258.3771ms str_replace is 11.87% faster
8192 chars str_replace 506.3410ms preg_replace 555.6269ms str_replace is 8.87% faster
16384 chars str_replace 1116.8811ms preg_replace 1098.0589ms preg_replace is 1.69% faster
32768 chars str_replace 2299.3128ms preg_replace 2222.8632ms preg_replace is 3.32% faster
Die Timings selbst beziehen sich auf 10000 Iterationen, aber was interessanter ist, sind die relativen Unterschiede. Bis zu 512 Zeichen sah ich immer, wie preg_replace gewann. Im Bereich von 1 bis 8 KB hatte str_replace eine Randkante.
Ich fand das Ergebnis interessant und habe es hier aufgenommen. Das Wichtigste ist nicht, dieses Ergebnis zu verwenden, um zu entscheiden, welche Methode verwendet werden soll, sondern um einen Benchmark mit Ihren eigenen Daten durchzuführen und dann zu entscheiden.
Viele der anderen Antworten hier berücksichtigen keine Unicode-Zeichen (z. B. öäüßйȝîûηы ე மி ᚉ ⠛). In diesem Fall können Sie Folgendes verwenden:
Es gibt eine seltsame Klasse von Zeichen im Bereich
\x80-\x9F
(knapp über dem 7-Bit-ASCII-Zeichenbereich), die technisch kontrollierte Zeichen sind, aber im Laufe der Zeit für druckbare Zeichen missbraucht wurden. Wenn Sie damit keine Probleme haben, können Sie Folgendes verwenden:Wenn Sie auch Zeilenvorschübe, Wagenrückläufe, Tabulatoren, nicht unterbrechende Leerzeichen und weiche Bindestriche entfernen möchten, können Sie Folgendes verwenden:
Beachten Sie, dass Sie für die obigen Beispiele einfache Anführungszeichen verwenden müssen .
Wenn Sie alles außer einfachen druckbaren ASCII-Zeichen entfernen möchten (alle obigen Beispielzeichen werden entfernt), können Sie Folgendes verwenden:
Referenz siehe http://www.fileformat.info/info/charset/UTF-8/list.htm
quelle
'/[\x00-\x1F\x80-\xC0]/u'
lässt sie intakt; aber auch Divisions- (F7) und Multiplikationszeichen (D7).\x7F-\x9F
?Ab PHP 5.2 haben wir auch Zugriff auf filter_var, von dem ich keine Erwähnung gesehen habe, also dachte ich, ich würde es da rauswerfen. So verwenden Sie filter_var, um nicht druckbare Zeichen <32 und> 127 zu entfernen:
Filtern Sie ASCII-Zeichen unter 32
Filtern Sie ASCII-Zeichen über 127
Ziehe beide aus:
Sie können auch niedrige Zeichen (Zeilenumbruch, Tabulator usw.) in HTML codieren, während Sie hohe Zeichen entfernen:
Es gibt auch Optionen zum Entfernen von HTML, zum Bereinigen von E-Mails und URLs usw. Es gibt also viele Optionen zum Bereinigen (Daten entfernen) und sogar zur Validierung (Rückgabe false, wenn nicht gültig, anstatt stillschweigend zu entfernen).
Desinfektion: http://php.net/manual/en/filter.filters.sanitize.php
Validierung: http://php.net/manual/en/filter.filters.validate.php
Es besteht jedoch immer noch das Problem, dass FILTER_FLAG_STRIP_LOW Zeilenumbrüche und Zeilenumbrüche entfernt, die für einen Textbereich vollständig gültige Zeichen sind. Einige der Regex-Antworten sind daher manchmal noch erforderlich, z. B. nach Überprüfung Thread, ich habe vor, dies für Textbereiche zu tun:
Dies scheint besser lesbar zu sein als eine Reihe von regulären Ausdrücken, die durch den numerischen Bereich entfernt wurden.
quelle
Sie können Zeichenklassen verwenden
quelle
das ist einfacher:
quelle
Alle Lösungen funktionieren teilweise, und selbst im Folgenden werden wahrscheinlich nicht alle Fälle abgedeckt. Mein Problem bestand darin, einen String in eine utf8-MySQL-Tabelle einzufügen. Die Zeichenfolge (und ihre Bytes) entsprachen alle utf8, hatten jedoch mehrere fehlerhafte Sequenzen. Ich gehe davon aus, dass die meisten von ihnen Kontrolle oder Formatierung waren.
Um das Problem weiter zu verschärfen, ist die Tabelle vs. Server vs. Verbindung vs. Rendering des Inhalts, wie hier ein wenig erwähnt
quelle
$s = preg_replace('/(\xF0\x9F[\x00-\xFF][\x00-\xFF])/', ' ', $s);
weil alle Emoji-Charaktere MySQL durcheinander brachtenMeine UTF-8-kompatible Version:
preg_replace('/[^\p{L}\s]/u','',$value);
quelle
Sie können einen regulären Express verwenden, um alles außer den Zeichen zu entfernen, die Sie behalten möchten:
Ersetzt alles, was nicht (^) die Buchstaben AZ oder az, die Zahlen 0-9, Leerzeichen, Unterstrich, Hypen, Plus und kaufmännisches Und ist - durch nichts (dh entfernen Sie es).
quelle
Dadurch werden alle Steuerzeichen ( http://uk.php.net/manual/en/regexp.reference.unicode.php ) entfernt, wobei die
\n
Zeilenumbruchzeichen verbleiben. Nach meiner Erfahrung sind die Steuerzeichen diejenigen, die am häufigsten die Druckprobleme verursachen.quelle
/u
für UTF-8-Zeichen hinzugefügt . Könnten Sie bitte erklären, was der erste Teil(?!\n)
tut?So entfernen Sie alle Nicht-ASCII-Zeichen aus der Eingabezeichenfolge
$result = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string);
Dieser Code entfernt alle Zeichen in den Hex-Bereichen 0-31 und 128-255, wobei nur die Hex-Zeichen 32-127 in der resultierenden Zeichenfolge verbleiben, die ich in diesem Beispiel $ result nenne.
quelle
Die Antwort von @PaulDixon
ist völlig falsch , da die druckbaren erweiterten ASCII-Zeichen 128-255 entfernt werden!wurde teilweise korrigiert. Ich weiß nicht, warum er immer noch 128-255 aus einem 7-Bit-ASCII-Satz mit 127 Zeichen löschen möchte, da er nicht die erweiterten ASCII-Zeichen enthält.Aber schließlich war es wichtig, 128-255 nicht zu löschen, da zum Beispiel
chr(128)
(\x80
) das Euro-Zeichen in 8-Bit-ASCII ist und viele UTF-8-Schriftarten in Windows ein Euro-Zeichen und Android in Bezug auf meinen eigenen Test anzeigen .Und es werden viele UTF-8-Zeichen getötet, wenn Sie die ASCII-Zeichen 128-255 aus einer UTF-8-Zeichenfolge entfernen (wahrscheinlich die Startbytes eines Multi-Byte-UTF-8-Zeichens). Also tu das nicht! Sie sind in allen derzeit verwendeten Dateisystemen völlig legal. Der einzige reservierte Bereich ist 0-31 .
Verwenden Sie stattdessen diese Option, um die nicht druckbaren Zeichen 0-31 und 127 zu löschen:
Es funktioniert in ASCII und UTF-8, da beide denselben Kontrollsatzbereich verwenden .
Die
schnellstelangsamere Alternative ohne reguläre Ausdrücke:Wenn Sie alle Leerzeichen behalten wollen
\t
,\n
und\r
dann entfernenchr(9)
,chr(10)
undchr(13)
aus dieser Liste. Hinweis: Das übliche Leerzeichen istchr(32)
so, dass es im Ergebnis bleibt. Entscheiden Sie selbst, ob Sie nicht unterbrechenden Speicherplatz entfernen möchten,chr(160)
da dies zu Problemen führen kann.¹ Von @PaulDixon getestet und von mir selbst verifiziert.
quelle
wie wäre es mit:
gibt mir die vollständige Kontrolle darüber, was ich einschließen möchte
quelle
Die markierte Antwort ist perfekt, es fehlt jedoch das Zeichen 127 (DEL), das ebenfalls nicht druckbar ist
Meine Antwort wäre
quelle
"cedivad" löste das Problem für mich mit anhaltendem Ergebnis der schwedischen Zeichen ÅÄÖ.
Vielen Dank!
quelle
Für alle, die immer noch nach Möglichkeiten suchen, ohne die nicht druckbaren Zeichen zu entfernen, sondern ihnen zu entkommen, habe ich dies gemacht, um zu helfen. Fühlen Sie sich frei, es zu verbessern! Zeichen werden nach \\ x [A-F0-9] [A-F0-9] maskiert.
Rufen Sie so an:
quelle
Ich habe das Problem für UTF8 mit https://github.com/neitanod/forceutf8 gelöst
quelle
Der Regex in der ausgewählten Antwort schlägt für Unicode fehl: 0x1d (mit PHP 7.4)
eine Lösung:
from: UTF 8 String entfernt alle unsichtbaren Zeichen außer Zeilenumbruch
quelle