76 votes

Suppression des caractères de contrôle de la chaîne PHP

Comment supprimer les caractères de contrôle comme STX d'une chaîne PHP ? J'ai joué avec

preg_replace("/[^a-zA-Z0-9 .\-_;!:?äÄöÖüÜß<>='\"]/","",$pString)

mais j'ai trouvé que ça enlevait beaucoup trop de choses. Existe-t-il un moyen d'enlever seulement des chars de contrôle ?

0 votes

Les liens suivants pourraient vous aider :<br/> Tableau des caractères ASCII <br /> Référence POSIX <br /> Expressions régulières

133voto

Stephan202 Points 27707

Si vous entendez par caractères de contrôle les les 32 premiers caractères ascii et \x7F (ce qui inclut le retour chariot, etc.), alors cela fonctionnera :

preg_replace('/[\x00-\x1F\x7F]/', '', $input);

(Notez les guillemets simples : avec des guillemets doubles, l'utilisation de \x00 provoque une erreur d'analyse, en quelque sorte).

Le saut de ligne et le retour chariot (souvent écrits \r y \n ) peuvent être sauvés de la suppression comme suit :

preg_replace('/[\x00-\x09\x0B\x0C\x0E-\x1F\x7F]/', '', $input);

Je dois dire que je pense La réponse de Bobby est meilleur, dans le sens où [:cntrl:] transmet mieux ce que fait le code que [\x00-\x1F\x7F] .

AVERTISSEMENT : ereg_replace est déprécié en PHP >= 5.3.0 et supprimé en PHP >= 7.0.0 !, veuillez utiliser preg_replace au lieu de ereg_replace :

preg_replace('/[[:cntrl:]]/', '', $input);

0 votes

Merci KB22. Notez que mon regex était incorrect lorsque vous avez accepté ma réponse. Veuillez voir la version mise à jour.

7 votes

Malheureusement, ereg_replace est déprécié en PHP 5.3 et la version mb est plus lente que preg_replace. Il existe une façon un peu plus propre de faire cela avec preg_replace, et dans mes tests, elle est très légèrement plus rapide (1% plus rapide quand on traite des centaines de milliers d'éléments) que la méthode ci-dessus : preg_replace('/[ \p {Cc}]/', '', $input) ;

9 votes

De plus, preg_replace('/[:cntrl :]]/', '', $input) ; a bien fonctionné pour moi (php 5.2.6).

49voto

Scott Jungwirth Points 361

Pour l'entrée Unicode, cela supprimera tous les caractères de contrôle, non assignés, à usage privé, de formatage et les points de code de substitution (qui ne sont pas également des caractères d'espace, tels que tabulation, nouvelle ligne) de votre texte d'entrée. Je l'utilise pour supprimer tous les caractères non imprimables de mon entrée.

<?php
$clean = preg_replace('/[^\PC\s]/u', '', $input);

pour plus d'informations sur \p{C} voir http://www.regular-expressions.info/unicode.html#category

0 votes

Pourquoi utilisez-vous \PC au lieu de \p{C} ?

0 votes

Nous devons utiliser une classe de caractères niés pour éviter de supprimer les espaces (puisqu'ils sont considérés comme invisibles), ce qui signifie que nous devons utiliser la forme inverse de \p{C}

1 votes

C'est exactement ce dont vous avez besoin lorsque vous envoyez des données utilisateur à l'API d'Authorize.net. Au cas où quelqu'un d'autre aurait des erreurs de caractères XML invalides.

24voto

Bobby Points 6894

PHP supporte les classes POSIX, vous pouvez donc utiliser [:cntrl:] au lieu de quelques trucs fantaisistes de magie de caractère :

ereg_replace("[:cntrl:]", "", $pString);

Editar:

Une paire supplémentaire de crochets pourrait être nécessaire en 5.3.

ereg_replace("[[:cntrl:]]", "", $pString);

1 votes

PHP supporte POSIX, en utilisant les fonctions ereg au lieu de preg : nl2.php.net/manuel/fr/book.regex.php

0 votes

J'ai testé celui-ci, les classes POSIX ne semblent pas fonctionner. Merci pour l'astuce en tout cas !

0 votes

Je dois me corriger, pour être plus précis : ereg fonctionne en acte.

6voto

Jamie Points 31

Pour conserver les caractères de contrôle tout en les rendant compatibles avec JSON, j'ai du

$str = preg_replace(
    array(
        '/\x00/', '/\x01/', '/\x02/', '/\x03/', '/\x04/',
        '/\x05/', '/\x06/', '/\x07/', '/\x08/', '/\x09/', '/\x0A/',
        '/\x0B/','/\x0C/','/\x0D/', '/\x0E/', '/\x0F/', '/\x10/', '/\x11/',
        '/\x12/','/\x13/','/\x14/','/\x15/', '/\x16/', '/\x17/', '/\x18/',
        '/\x19/','/\x1A/','/\x1B/','/\x1C/','/\x1D/', '/\x1E/', '/\x1F/'
    ), 
    array(
        "\u0000", "\u0001", "\u0002", "\u0003", "\u0004",
        "\u0005", "\u0006", "\u0007", "\u0008", "\u0009", "\u000A",
        "\u000B", "\u000C", "\u000D", "\u000E", "\u000F", "\u0010", "\u0011",
        "\u0012", "\u0013", "\u0014", "\u0015", "\u0016", "\u0017", "\u0018",
        "\u0019", "\u001A", "\u001B", "\u001C", "\u001D", "\u001E", "\u001F"
    ), 
    $str
);

(Les règles JSON stipulent : " Tous les caractères Unicode peuvent être placés entre les guillemets, à l'exception des caractères qui doivent être échappés : guillemets, solidus inversé et les caractères de contrôle (U+0000 à U+001F) ").

1voto

Anthony Points 14424

Méthode sans regex

Si vous ne zappez que les caractères de contrôle que je connais (ceux inférieurs à 32 et 127), essayez ceci :

 for($control = 0; $control < 32; $control++) {
     $pString = str_replace(chr($control), "", $pString;
 }

$pString = str_replace(chr(127), "", $pString;

La boucle se débarrasse de tout sauf de DEL, que nous ajoutons à la fin.

Je pense que cela sera beaucoup moins stressant pour vous et le script que de traiter avec regex et la bibliothèque regex.

Mise à jour de la méthode sans regex

Juste pour le plaisir, j'ai trouvé une autre façon de le faire. Celle-ci le fait en utilisant un tableau de caractères de contrôle :

$ctrls = range(chr(0), chr(31));
$ctrls[] = chr(127);

$clean_string = str_replace($ctrls, "", $string);

1 votes

En quoi cela est-il moins "stressant" que ereg_replace("[:cntrl :]", "", $pString) ; ? En utilisant ereg, l'interpréteur PHP compilera probablement un code intermédiaire plus efficace qu'en utilisant cette boucle for de toute façon.

6 votes

Ereg_replace est déprécié à partir de php 5.3.0

0 votes

C'est un cas où les expressions rationnelles sont probablement plus lisibles. Mais j'aime cette réponse car elle a probablement un avantage en termes de performances et fonctionnera sans problème sur pratiquement toutes les installations PHP. Bravo !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X