[解決済み] Python で文字列から ANSI エスケープシーケンスを削除するにはどうすればよいですか?
質問
これは私の文字列です。
'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
SSHコマンドの出力を取得するコードを使用していて、文字列には'examplefile.zip'のみを含めるようにしたい。
余分なエスケープシーケンスを削除するために使用できるものは何ですか?
どのように解決するのですか?
正規表現で削除してください。
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)
または
VERBOSE
フラグがない場合は、凝縮された形で
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])')
result = ansi_escape.sub('', sometext)
デモです。
>>> 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'
上記の正規表現は7ビットのANSI C1エスケープシーケンスを全てカバーしますが ではなく 8ビットのC1エスケープシーケンスオープナーは含まれません。後者は、同じ範囲のバイトが異なる意味を持つ今日の UTF-8 の世界では決して使用されません。
8ビットコードもカバーする必要がある場合(そして、おそらくは
bytes
値で作業していると思われます)、正規表現は次のようなバイト パターンになります。
# 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)
であり、これは以下のように凝縮されます。
# 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)
詳しくは
- は ANSIエスケープコードの概要 ウィキペディア
- ECMA-48 標準、第 5 版 (特に 5.3 節と 5.3 節)
あなたが挙げた例では、4つのCSI (Control Sequence Introducer) コードが含まれており、これは
\x1B[
または
ESC
[
で終わっているため、それぞれSGR(Select Graphic Rendition)コードを含んでいます。
m
. パラメータは (
;
セミコロンで区切られた) パラメータは、どのようなグラフィック表示属性を使用するかを端末に伝えます。つまり、それぞれの
\x1B[....m
の並びに対して、使われる3つのコードは次の通りです。
-
0(または
00
この例では)。 リセット は、すべての属性を無効にする -
1 (または
01
の例では)。 太字 - 31: 赤 (前景)
しかし、ANSI には CSI SGR コード以上のものがあります。CSI だけでも、カーソルを制御したり、行やディスプレイ全体を消去したり、スクロールしたりできます (もちろん、端末がこれをサポートしていればの話ですが)。また、CSI 以外にも、代替フォントを選択するためのコード (
SS2
と
SS3
)、「プライベートメッセージ」(パスワードと同じ)の送信、端末との通信(
DCS
)、OS (
OSC
)、あるいはアプリケーション自体 (
APC
は、アプリケーションがカスタム制御コードを通信ストリームにピギーバックする方法です)、さらに文字列を定義するのに役立つコード (
SOS
, 文字列の開始。
ST
文字列終端記号)、あるいは、すべてを基本状態に戻す(
RIS
). 上記の正規表現はこれらすべてをカバーしています。
しかし、上記の正規表現は ANSI C1 コードのみを削除し、これらのコードがマークアップしている可能性のある追加データ (OSC オープナーと終了 ST コードの間に送信される文字列など) は削除しないことに注意してください。これらを削除するには、この回答の範囲外の追加作業が必要です。
関連
-
[解決済み] PandasでDataFrameの行を反復処理する方法
-
[解決済み] 文字列の単語を反復処理するにはどうすればよいですか?
-
[解決済み] バイトを文字列に変換する
-
[解決済み] Pythonの辞書からキーを削除するにはどうしたらいいですか?
-
[解決済み] YAML の文字列を複数行に渡って分割するには?
-
[解決済み] Javaで文字列を分割する方法
-
[解決済み】JavaScriptで文字列の出現箇所をすべて置換する方法
-
[解決済み】ネストされたディレクトリを安全に作成するには?
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] djangoフレームワークでフォームフィールドから値を取得するには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] Pythonの構文に新しいステートメントを追加することはできますか?
-
[解決済み] DataFrameに日付間の日数カラムを追加する pandas
-
[解決済み] 値で列挙名を取得する [重複]。
-
[解決済み] pandasのタイムゾーンに対応したDateTimeIndexを、特定のタイムゾーンに対応したナイーブなタイムスタンプに変換する。
-
[解決済み] Jupyter (IPython)ノートブックのセッションをpickleして保存する方法
-
[解決済み] Flask でグローバル変数はスレッドセーフか?リクエスト間でデータを共有するには?
-
[解決済み] matplotlib でプロットの軸、目盛、ラベルの色を変更する方法
-
[解決済み] if 節の終了方法
-
[解決済み] Pythonの文字列の前にあるbという接頭辞は何を意味するのですか?
-
[解決済み] virtualenvsはどこに作成するのですか?