Ich habe ein Problem mit dem Entfernen von Nicht-Utf8-Zeichen aus der Zeichenfolge, die nicht richtig angezeigt werden. Zeichen sind wie folgt 0x97 0x61 0x6C 0x6F (hexadezimale Darstellung)
Was ist der beste Weg, um sie zu entfernen? Regulärer Ausdruck oder etwas anderes?
Antworten:
Verwenden eines Regex-Ansatzes:
Es sucht nach UTF-8-Sequenzen und erfasst diese in Gruppe 1. Es stimmt auch mit einzelnen Bytes überein, die nicht als Teil einer UTF-8-Sequenz identifiziert werden konnten, diese jedoch nicht erfassen. Ersetzen ist alles, was in Gruppe 1 erfasst wurde. Dadurch werden effektiv alle ungültigen Bytes entfernt.
Es ist möglich, die Zeichenfolge zu reparieren, indem die ungültigen Bytes als UTF-8-Zeichen codiert werden. Wenn die Fehler jedoch zufällig sind, können einige seltsame Symbole zurückbleiben.
BEARBEITEN:
!empty(x)
stimmt mit nicht leeren Werten überein ("0"
wird als leer betrachtet).x != ""
stimmt mit nicht leeren Werten überein, einschließlich"0"
.x !== ""
passt zu allem außer""
.x != ""
scheint in diesem Fall die beste zu sein.Ich habe das Match auch ein wenig beschleunigt. Anstatt jedes Zeichen einzeln abzugleichen, werden Sequenzen gültiger UTF-8-Zeichen abgeglichen.
quelle
$regex = <<<'END'
für PHP <5.3.x verwendet werden?elseif (!empty($captures([2])) {
Sie!== ""
anstelle von leer verwenden sollten, da er"0"
als leer betrachtet wird. Auch diese Funktion ist sehr langsam, könnte dies schneller erfolgen?Wenn Sie
utf8_encode()
eine bereits UTF8-Zeichenfolge anwenden , wird eine verstümmelte UTF8-Ausgabe zurückgegeben.Ich habe eine Funktion erstellt, die all diese Probleme behebt. Es heißt
Encoding::toUTF8()
.Sie müssen nicht wissen, wie Ihre Zeichenfolgen codiert sind. Es kann Latin1 (ISO8859-1), Windows-1252 oder UTF8 sein, oder die Zeichenfolge kann eine Mischung aus diesen haben.
Encoding::toUTF8()
konvertiert alles in UTF8.Ich habe es getan, weil mir ein Dienst einen Datenfeed gegeben hat, der alles durcheinander gebracht hat und diese Codierungen in derselben Zeichenfolge gemischt hat.
Verwendung:
Ich habe eine weitere Funktion hinzugefügt, Encoding :: fixUTF8 (), die jede UTF8-Zeichenfolge korrigiert, die nach mehrmaliger Codierung in UTF8 verstümmelt aussieht.
Verwendung:
Beispiele:
wird ausgegeben:
Herunterladen:
https://github.com/neitanod/forceutf8
quelle
Sie können mbstring verwenden:
... entfernt ungültige Zeichen.
Siehe: Durch Ersetzen ungültiger UTF-8-Zeichen durch Fragezeichen wird mbstring.substitute_character ignoriert
quelle
<0x1a>
<0x1a>
, obwohl kein druckbares Zeichen, ist eine perfekt gültige UTF-8-Sequenz. Möglicherweise haben Sie Probleme mit nicht druckbaren Zeichen? Überprüfen Sie dies: stackoverflow.com/questions/1176904/…ini_set('mbstring.substitute_character', 'none');
sonst bekam ich Fragezeichen im Ergebnis.Diese Funktion entfernt alle NICHT-ASCII-Zeichen. Sie ist nützlich, löst aber nicht die Frage:
Dies ist meine Funktion, die unabhängig von der Codierung immer funktioniert:
Wie es funktioniert:
quelle
í
Zeichen im Adressfeld, das ein gültiges UTF-8-Zeichen ist ( siehe Tabelle) . Die Moral: API-Fehlermeldungen nicht vertrauen :)Das benutze ich. Scheint ziemlich gut zu funktionieren. Entnommen aus http://planetozh.com/blog/2005/01/remove-invalid-characters-in-utf-8/
quelle
Versuche dies:
Laut iconv-Handbuch die Funktion den ersten Parameter als Eingabezeichensatz, den zweiten Parameter als Ausgabezeichensatz und den dritten als tatsächliche Eingabezeichenfolge.
Wenn Sie sowohl den Eingabe- als auch den Ausgabezeichensatz auf UTF-8 setzen und das
//IGNORE
Flag an den Ausgabezeichensatz anhängen , werden alle Zeichen in der Eingabezeichenfolge gelöscht, die nicht durch den Ausgabezeichensatz dargestellt werden können. Somit wird die Eingabezeichenfolge effektiv gefiltert.quelle
//IGNORE
scheint den Hinweis nicht zu unterdrücken, dass ungültiges UTF-8 vorhanden ist (was ich natürlich weiß und beheben möchte). Ein hoch bewerteter Kommentar im Handbuch scheint zu glauben, dass es sich seit einigen Jahren um einen Fehler handelt.iconv
. @halfer Möglicherweise stammen Ihre Eingabedaten nicht von utf-8. Eine andere Möglichkeit besteht darin, eine erneute Konvertierung in ASCII und dann wieder zurück in utf-8 durchzuführen. In meinem Fall habe ichiconv
wie$output = iconv("UTF-8//", "ISO-8859-1//IGNORE", $input );
Der Text kann Nicht-utf8-Zeichen enthalten . Versuchen Sie zuerst:
Weitere Informationen finden Sie hier: http://php.net/manual/en/function.mb-convert-encoding.php news
quelle
UConverter kann seit PHP 5.5 verwendet werden. UConverter ist die bessere Wahl, wenn Sie die Erweiterung intl und nicht mbstring verwenden.
htmlspecialchars können verwendet werden, um ungültige Bytesequenzen seit PHP 5.4 zu entfernen. Htmlspecialchars ist besser als preg_match, um große Bytes und die Genauigkeit zu verarbeiten. Viele der falschen Implementierungen durch die Verwendung von regulären Ausdrücken sind erkennbar.
quelle
Ich habe eine Funktion erstellt, die ungültige UTF-8-Zeichen aus einer Zeichenfolge löscht. Ich verwende es, um die Beschreibung von 27000 Produkten zu löschen, bevor die XML-Exportdatei generiert wird.
quelle
ord()
Gibt Ergebnisse im Bereich von 0 bis 255 zurück. Der Rieseif
in dieser Funktion testet auf Unicode-Bereiche,ord()
die niemals zurückkehren werden. Wenn jemand klären möchte, warum diese Funktion so funktioniert, würde ich die Einsicht schätzen.Willkommen zu 2019 und dem
/u
Modifikator in Regex, der UTF-8-Multibyte-Zeichen für Sie verarbeitetWenn Sie nur verwenden
mb_convert_encoding($value, 'UTF-8', 'UTF-8')
, werden immer noch nicht druckbare Zeichen in Ihrer Zeichenfolge angezeigtDiese Methode wird:
mb_convert_encoding
\r
,\x00
(NULL-Byte) und andere Steuer Zeichen mitpreg_replace
Methode:
[:print:]
\n
Passen Sie alle druckbaren Zeichen und Zeilenumbrüche an und entfernen Sie alles andereSie können die ASCII-Tabelle unten sehen. Die druckbaren Zeichen reichen von 32 bis 127, aber Zeilenumbruch
\n
ist Teil der Steuerzeichen, die von 0 bis 31 reichen, sodass wir dem regulären Ausdruck Zeilenumbruch hinzufügen müssen/[^[:print:]\n]/u
Sie können versuchen, Zeichenfolgen mit Zeichen außerhalb des druckbaren Bereichs wie
\x7F
(DEL),\x1B
(Esc) usw. durch die Regex zu senden und zu sehen, wie sie entfernt werdenhttps://www.tehplayground.com/q5sJ3FOddhv1atpR
quelle
php-mbstring
standardmäßig nicht in PHP gepackt ist.quelle
Vom letzten Patch zum JSON-Parser-Modul Feeds von Drupal:
Wenn Sie besorgt sind, werden Leerzeichen als gültige Zeichen beibehalten.
Habe was ich brauchte. Es entfernt heutzutage weit verbreitete Emoji-Zeichen, die nicht in den 'utf8'-Zeichensatz von MySQL passen und die mir Fehler wie "SQLSTATE [HY000]: Allgemeiner Fehler: 1366 Falscher Zeichenfolgenwert" gaben.
Weitere Informationen finden Sie unter https://www.drupal.org/node/1824506#comment-6881382
quelle
iconv
ist weitaus besser als das altmodische Regexp-basiertepreg_replace
, das heutzutage veraltet ist.ereg_replace()
, tut mir leid.Vielleicht nicht die genaueste Lösung, aber sie erledigt die Arbeit mit einer einzigen Codezeile:
utf8_decode
konvertiert die Zeichen in ein Fragezeichen;str_replace
wird die Fragezeichen entfernen.quelle
Die Regeln lauten also, dass für das erste UTF-8- Oktlet das High-Bit als Marker gesetzt ist und dann 1 bis 4 Bits, um anzugeben, wie viele zusätzliche Octlets vorhanden sind. dann müssen für jedes der zusätzlichen Oktlets die hohen zwei Bits auf 10 gesetzt sein.
Die Pseudo-Python wäre:
Dieselbe Logik sollte in PHP übersetzbar sein. Es ist jedoch nicht klar, welche Art von Strippen durchgeführt werden soll, wenn Sie einen missgebildeten Charakter erhalten.
quelle
c = (ch << 1)
wird(c & 1)
beim ersten Mal Null machen und die Schleife überspringen. Der Test sollte wahrscheinlich sein(c & 128)
So entfernen Sie alle Unicode-Zeichen außerhalb der Unicode-Grundspracheebene:
quelle
Etwas anders als die Frage, aber ich verwende HtmlEncode (Zeichenfolge).
Pseudocode hier
Eingabe und Ausgabe
Ich weiß, dass es nicht perfekt ist, aber es macht den Job für mich.
quelle
es funktioniert auf unseren Service
quelle
Wie wäre es mit iconv:
http://php.net/manual/en/function.iconv.php
Ich habe es nicht in PHP selbst verwendet, aber es hat in der Kommandozeile immer gute Ergebnisse für mich erzielt. Sie können damit ungültige Zeichen ersetzen.
quelle