Supprimez-les avec une expression régulière :
import re
# 7-bit C1 ANSI sequences
ansi_escape = re.compile(r'''
\x1B # ESC
(?: # 7-bit C1 Fe (except CSI)
[@-Z\\-_]
| # or [ for CSI, followed by a control sequence
\[
[0-?]* # Parameter bytes
[ -/]* # Intermediate bytes
[@-~] # Final byte
)
''', re.VERBOSE)
result = ansi_escape.sub('', sometext)
ou, sans le VERBOSE
drapeau, sous forme condensée :
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', sometext)
Démonstration :
>>> import re
>>> ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
>>> sometext = 'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
>>> ansi_escape.sub('', sometext)
'ls\r\nexamplefile.zip\r\n'
L'expression régulière ci-dessus couvre toutes les séquences d'échappement ANSI C1 de 7 bits, mais pas les ouvreurs de séquence d'échappement C1 8 bits. Ces derniers ne sont jamais utilisés dans le monde UTF-8 actuel, où la même plage d'octets a une signification différente.
Si vous avez besoin de couvrir également les codes 8 bits (et que vous travaillez alors, vraisemblablement, avec bytes
), l'expression régulière devient alors un motif d'octets comme celui-ci :
# 7-bit and 8-bit C1 ANSI sequences
ansi_escape_8bit = re.compile(br'''
(?: # either 7-bit C1, two bytes, ESC Fe (omitting CSI)
\x1B
[@-Z\\-_]
| # or a single 8-bit byte Fe (omitting CSI)
[\x80-\x9A\x9C-\x9F]
| # or CSI + control codes
(?: # 7-bit CSI, ESC [
\x1B\[
| # 8-bit CSI, 9B
\x9B
)
[0-?]* # Parameter bytes
[ -/]* # Intermediate bytes
[@-~] # Final byte
)
''', re.VERBOSE)
result = ansi_escape_8bit.sub(b'', somebytesvalue)
qui peut être condensé en
# 7-bit and 8-bit C1 ANSI sequences
ansi_escape_8bit = re.compile(
br'(?:\x1B[@-Z\\-_]|[\x80-\x9A\x9C-\x9F]|(?:\x1B\[|\x9B)[0-?]*[ -/]*[@-~])'
)
result = ansi_escape_8bit.sub(b'', somebytesvalue)
Pour plus d'informations, voir :
L'exemple que vous avez donné contient 4 codes CSI (Control Sequence Introducer), comme l'indique le symbole \x1B[
o ESC [
et chacun d'entre eux contient un code SGR (Select Graphic Rendition), car ils se terminent tous par l'expression m
. Les paramètres (séparés par ;
Les points-virgules) entre ceux-ci indiquent à votre terminal les attributs de rendu graphique à utiliser. Ainsi, pour chaque \x1B[....m
les 3 codes utilisés sont les suivants :
- 0 (ou
00
dans cet exemple) : réinitialiser Désactiver tous les attributs
- 1 (ou
01
dans l'exemple) : en gras
- 31 : rouge (premier plan)
Cependant, l'ANSI ne se limite pas aux codes CSI SGR. Avec CSI uniquement, vous pouvez également contrôler le curseur, effacer des lignes ou l'ensemble de l'affichage, ou encore faire défiler l'écran (à condition que le terminal le supporte, bien sûr). Et au-delà de CSI, il existe des codes pour sélectionner des polices alternatives ( SS2
y SS3
), pour envoyer des "messages privés" (pensez aux mots de passe), pour communiquer avec le terminal ( DCS
), l'OS ( OSC
), ou l'application elle-même ( APC
un moyen pour les applications d'ajouter des codes de contrôle personnalisés au flux de communication), et d'autres codes pour aider à définir les chaînes de caractères ( SOS
, Début de la chaîne, ST
String Terminator) ou pour tout réinitialiser à un état de base ( RIS
). Les regex ci-dessus couvrent tous ces éléments.
Notez que la regex ci-dessus ne supprime que les codes ANSI C1, et non les données supplémentaires que ces codes peuvent marquer (comme les chaînes envoyées entre un ouvreur OSC et le code ST de terminaison). Leur suppression nécessiterait un travail supplémentaire qui sort du cadre de cette réponse.