J'imagine que je dois supprimer les caractères 0-31 et 127.
Existe-t-il une fonction ou un morceau de code permettant de réaliser cette opération de manière efficace ?
J'imagine que je dois supprimer les caractères 0-31 et 127.
Existe-t-il une fonction ou un morceau de code permettant de réaliser cette opération de manière efficace ?
Si votre Tardis vient d'atterrir en 1963, et que vous ne voulez que les caractères ASCII de 7 bits imprimables, vous pouvez tout arracher de 0-31 et 127-255 avec ceci :
$string = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $string);
Il correspond à tout ce qui se trouve dans les plages 0-31, 127-255 et le supprime.
Vous êtes tombé dans une machine à remonter le temps, et vous êtes de retour dans les années 80. Si vous disposez d'une forme d'ASCII 8 bits, il est préférable de conserver les caractères dans la plage 128-255. Un ajustement facile - il suffit de chercher 0-31 et 127.
$string = preg_replace('/[\x00-\x1F\x7F]/', '', $string);
Ah, bienvenue au 21ème siècle. Si vous avez une chaîne de caractères encodée en UTF-8, alors la fonction /u
modificateur peut être utilisé sur le regex
$string = preg_replace('/[\x00-\x1F\x7F]/u', '', $string);
Cela supprime simplement les valeurs 0-31 et 127. Cela fonctionne en ASCII et en UTF-8, car les deux partagent le même nom. même plage de réglage du contrôle (comme indiqué par mgutt ci-dessous). Strictement parlant, cela fonctionnerait sans l'option /u
modificateur. Mais cela facilite la vie si vous voulez supprimer d'autres personnages...
Si vous avez affaire à Unicode, il y a potentiellement de nombreux éléments non imprimables mais considérons un cas simple : ESPACE SANS COUPURE (U+00A0)
Dans une chaîne UTF-8, cela serait codé comme suit 0xC2A0
. Vous pourriez rechercher et supprimer cette séquence spécifique, mais avec la /u
en place, vous pouvez simplement ajouter \xA0
à la classe de caractères :
$string = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $string);
preg_replace est assez efficace, mais si vous effectuez souvent cette opération, vous pouvez construire un tableau des caractères que vous voulez supprimer, et utiliser str_replace comme indiqué par mgutt ci-dessous, par ex.
//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);
Intuitivement, cela semble être rapide, mais ce n'est pas toujours le cas. Vous devez absolument faire un test pour voir si cela vous fait économiser quelque chose. J'ai fait quelques tests sur une variété de chaînes de caractères avec des données aléatoires, et ce modèle est apparu avec php 7.0.12.
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
Les temps sont calculés pour 10000 itérations, mais ce qui est plus intéressant, ce sont les différences relatives. Jusqu'à 512 caractères, je voyais preg_replace toujours gagnant. Dans la gamme 1-8kb, str_replace avait un avantage marginal.
J'ai pensé que c'était un résultat intéressant, donc je l'inclus ici. L'important n'est pas de prendre ce résultat et de l'utiliser pour décider de la méthode à utiliser, mais de le comparer à vos propres données et de décider ensuite.
Si vous devez considérer qu'une nouvelle ligne est sûre, changez l'expression en ceci (recherche inversée pour les imprimables) : preg_replace(/[^ \x0A\x20 - \x7E ]/,'',$string) ;
@Dalin Il n'existe pas de "caractère UTF-8". Il existe des symboles/caractères Unicode, et UTF-8 est un encodage qui peut les représenter tous. Vous vouliez dire que cela ne fonctionne pas pour les caractères en dehors du jeu de caractères ASCII.
De nombreuses autres réponses ne prennent pas en compte les caractères unicodes (par exemple, öäüßîû ). Dans ce cas, vous pouvez utiliser ce qui suit :
$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]/u', '', $string);
Il y a une classe étrange de personnages dans la gamme \x80-\x9F
(juste au-dessus de la gamme de caractères ASCII de 7 bits) qui sont techniquement des caractères de contrôle, mais qui, au fil du temps, ont été utilisés à tort comme caractères imprimables. Si vous n'avez pas de problèmes avec ces caractères, vous pouvez les utiliser :
$string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/u', '', $string);
Si vous souhaitez également supprimer les sauts de ligne, les retours de chariot, les tabulations, les espaces insécables et les tirets souples, vous pouvez utiliser :
$string = preg_replace('/[\x00-\x1F\x7F-\xA0\xAD]/u', '', $string);
Notez que vous doit utilisez des guillemets simples pour les exemples ci-dessus.
Si vous souhaitez supprimer tout ce qui n'est pas des caractères ASCII imprimables de base (tous les caractères d'exemple ci-dessus seront supprimés), vous pouvez utiliser :
$string = preg_replace( '/[^[:print:]]/', '',$string);
Pour référence, voir http://www.fileformat.info/info/charset/UTF-8/list.htm
Votre regexp traite bien les caractères UTF8, mais il élimine les caractères "spéciaux" non-UTF8, comme ç, ü et ö. '/[\x00-\x1F\x80-\xC0]/u'
les laisse intacts ; mais aussi le signe de la division (F7) et de la multiplication (D7).
@Hazar oui vous avez raison \x80 - \xFF trop dépouillé, mais \x80 - \xC0 est encore trop restrictive. Cela laisserait de côté d'autres caractères imprimables comme ©£±. Pour référence, voir utf8-chartable.de
Le troisième exemple avec :print : se comporte différemment selon les machines. Il fonctionne sur localhost, mais ne supprime pas les mêmes caractères sur notre serveur live. Le premier exemple a supprimé les chiffres réguliers de ma chaîne sur localhost.
@Dalin Il n'existe pas de "caractère UTF-8". Il existe des symboles/caractères Unicode, et UTF-8 est un encodage qui peut les représenter tous. Vous vouliez dire ces bandes caractères hors de la plage ASCII également.
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.