파이썬의 문자열에서 ANSI 이스케이프 시퀀스를 제거하려면 어떻게 해야 합니까?
여기 제 문자열이 포함된 스니펫이 있습니다.
'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
내가 실행한 SSH 명령에서 문자열이 반환되었습니다.문자열에 ANSI 표준 이스케이프 시퀀스가 포함되어 있기 때문에 현재 상태에서 사용할 수 없습니다.이스케이프 시퀀스를 프로그래밍 방식으로 제거하여 남은 문자열의 유일한 부분은 다음과 같습니다.
정규식으로 삭제:
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
values)다음과 .
# 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.4)
의 CSI Introducer), "Control Sequence Introducer" 4개의 CSI(Control Sequence Introducer) 코드가 표시되어 .\x1B[
또는 ESC를 여는 바이트, 그리고 각각은 SGR (Select Graphic Rendition) 코드를 포함합니다. 왜냐하면 그것들은 각각 다음과 같이 끝나기 때문입니다.m
」(「 」)로 );
세미콜론(semicolon)은 사용할 그래픽 렌더링 속성을 단말기에 알려줍니다. 각각의 래서각자에 요.\x1B[....m
시퀀스에 사용되는 3가지 코드는 다음과 같습니다.
- 0(또는)
00
이 예에서는): 재설정, 모든 특성 사용 안 함 - 1(또는)
01
예제): 굵게 표시 - 31: 빨간색(전경)
그러나 ANSI에는 CSI SGR 코드 이상의 것이 있습니다.CSI 단독으로 커서, 선 또는 전체 디스플레이를 지우거나 스크롤할 수도 있습니다(물론 단말기가 이를 지원하는 경우).CSI 에도 대체폰트를 코드가 (Code to select fonts).SS2
그리고.SS3
' 메시지passwords하기 위해(), '메시지를 보냅니다.DCS
(), OS(OSC
응용 자체입니다.APC
이 사용자 ) 하는 데 (예: 문자열 정의)SOS
of String, 문열시작자,,ST
Terminator) 모든 기본 상태(String Terminator)로합니다.RIS
은 이 것을 위의 정규식은 이 모든 것을 포함합니다.
그러나 위 정규식은 ANSI C1 코드만 제거하고 해당 코드가 표시할 수 있는 추가 데이터(예: OSC 오프너와 종료 ST 코드 사이에 전송되는 문자열)는 제거하지 않습니다.이러한 항목을 제거하려면 이 답변의 범위를 벗어나는 추가 작업이 필요합니다.
허용된 답변은 전경 색상 및 텍스트 스타일을 변경하도록 포맷된 ANSI 표준화된 이스케이프 시퀀스만 고려합니다.많은 시퀀스가 다음으로 끝나지 않습니다.'m'
예: 커서 위치 지정, 지우기 및 스크롤 영역.아래의 패턴은 전경색과 텍스트 스타일을 설정하는 것을 넘어 모든 경우를 포함하려고 시도합니다.
다음은 ANSI 표준 제어 시퀀스에 대한 정규식입니다.
/(\x9B|\x1B\[)[0-?]*[ -\/]*[@-~]/
추가 참조:
기능.
Jeff의 정규 표현에 대한 Martjn Pieters♦의 답변을 기반으로 합니다.
def escape_ansi(line):
ansi_escape = re.compile(r'(?:\x1B[@-_]|[\x80-\x9F])[0-?]*[ -/]*[@-~]')
return ansi_escape.sub('', line)
시험
def test_remove_ansi_escape_sequence(self):
line = '\t\u001b[0;35mBlabla\u001b[0m \u001b[0;36m172.18.0.2\u001b[0m'
escaped_line = escape_ansi(line)
self.assertEqual(escaped_line, '\tBlabla 172.18.0.2')
테스트
직접실려사다용다니합음을면하행다사니▁if▁use합▁it▁by를 사용합니다.python3
(유니코드 지원 향상, blabla).테스트 파일은 다음과 같습니다.
import unittest
import re
def escape_ansi(line):
…
class TestStringMethods(unittest.TestCase):
def test_remove_ansi_escape_sequence(self):
…
if __name__ == '__main__':
unittest.main()
제안된 정규식이 저에게 도움이 되지 않아서 저는 저만의 정규식을 만들었습니다.다음은 여기에 있는 사양을 기반으로 만든 파이썬 정규식입니다.
ansi_regex = r'\x1b(' \
r'(\[\??\d+[hl])|' \
r'([=<>a-kzNM78])|' \
r'([\(\)][a-b0-2])|' \
r'(\[\d{0,2}[ma-dgkjqi])|' \
r'(\[\d+;\d+[hfy]?)|' \
r'(\[;?[hf])|' \
r'(#[3-68])|' \
r'([01356]n)|' \
r'(O[mlnp-z]?)|' \
r'(/Z)|' \
r'(\d+)|' \
r'(\[\?\d;\d0c)|' \
r'(\d;\dR))'
ansi_escape = re.compile(ansi_regex, flags=re.IGNORECASE)
다음 스니펫에서 정규식을 테스트했습니다(ascii-table.com 페이지에서 복사 붙여넣기 포함).
\x1b[20h Set
\x1b[?1h Set
\x1b[?3h Set
\x1b[?4h Set
\x1b[?5h Set
\x1b[?6h Set
\x1b[?7h Set
\x1b[?8h Set
\x1b[?9h Set
\x1b[20l Set
\x1b[?1l Set
\x1b[?2l Set
\x1b[?3l Set
\x1b[?4l Set
\x1b[?5l Set
\x1b[?6l Set
\x1b[?7l Reset
\x1b[?8l Reset
\x1b[?9l Reset
\x1b= Set
\x1b> Set
\x1b(A Set
\x1b)A Set
\x1b(B Set
\x1b)B Set
\x1b(0 Set
\x1b)0 Set
\x1b(1 Set
\x1b)1 Set
\x1b(2 Set
\x1b)2 Set
\x1bN Set
\x1bO Set
\x1b[m Turn
\x1b[0m Turn
\x1b[1m Turn
\x1b[2m Turn
\x1b[4m Turn
\x1b[5m Turn
\x1b[7m Turn
\x1b[8m Turn
\x1b[1;2 Set
\x1b[1A Move
\x1b[2B Move
\x1b[3C Move
\x1b[4D Move
\x1b[H Move
\x1b[;H Move
\x1b[4;3H Move
\x1b[f Move
\x1b[;f Move
\x1b[1;2 Move
\x1bD Move/scroll
\x1bM Move/scroll
\x1bE Move
\x1b7 Save
\x1b8 Restore
\x1bH Set
\x1b[g Clear
\x1b[0g Clear
\x1b[3g Clear
\x1b#3 Double-height
\x1b#4 Double-height
\x1b#5 Single
\x1b#6 Double
\x1b[K Clear
\x1b[0K Clear
\x1b[1K Clear
\x1b[2K Clear
\x1b[J Clear
\x1b[0J Clear
\x1b[1J Clear
\x1b[2J Clear
\x1b5n Device
\x1b0n Response:
\x1b3n Response:
\x1b6n Get
\x1b[c Identify
\x1b[0c Identify
\x1b[?1;20c Response:
\x1bc Reset
\x1b#8 Screen
\x1b[2;1y Confidence
\x1b[2;2y Confidence
\x1b[2;9y Repeat
\x1b[2;10y Repeat
\x1b[0q Turn
\x1b[1q Turn
\x1b[2q Turn
\x1b[3q Turn
\x1b[4q Turn
\x1b< Enter/exit
\x1b= Enter
\x1b> Exit
\x1bF Use
\x1bG Use
\x1bA Move
\x1bB Move
\x1bC Move
\x1bD Move
\x1bH Move
\x1b12 Move
\x1bI
\x1bK
\x1bJ
\x1bZ
\x1b/Z
\x1bOP
\x1bOQ
\x1bOR
\x1bOS
\x1bA
\x1bB
\x1bC
\x1bD
\x1bOp
\x1bOq
\x1bOr
\x1bOs
\x1bOt
\x1bOu
\x1bOv
\x1bOw
\x1bOx
\x1bOy
\x1bOm
\x1bOl
\x1bOn
\x1bOM
\x1b[i
\x1b[1i
\x1b[4i
\x1b[5i
이것이 다른 사람들에게 도움이 되기를 바랍니다 :)
OSC 시퀀스를 사용하는 경우 정규식 솔루션이 작동하지 않았습니다(\x1b]
)
실제로 가시적인 출력을 렌더링하려면 파이테와 같은 터미널 에뮬레이터가 필요합니다.
#! /usr/bin/env python3
import pyte # terminal emulator: render terminal output to visible characters
pyte_screen = pyte.Screen(80, 24)
pyte_stream = pyte.ByteStream(pyte_screen)
bytes_ = b''.join([
b'$ cowsay hello\r\n', b'\x1b[?2004l', b'\r', b' _______\r\n',
b'< hello >\r\n', b' -------\r\n', b' \\ ^__^\r\n',
b' \\ (oo)\\_______\r\n', b' (__)\\ )\\/\\\r\n',
b' ||----w |\r\n', b' || ||\r\n',
b'\x1b]0;user@laptop1:/tmp\x1b\\', b'\x1b]7;file://laptop1/tmp\x1b\\', b'\x1b[?2004h$ ',
])
pyte_stream.feed(bytes_)
# pyte_screen.display always has 80x24 characters, padded with whitespace
# -> use rstrip to remove trailing whitespace from all lines
text = ("".join([line.rstrip() + "\n" for line in pyte_screen.display])).strip() + "\n"
print("text", text)
print("cursor", pyte_screen.cursor.y, pyte_screen.cursor.x)
print("title", pyte_screen.title)
향후 스택 오버플로에 도움이 된다면 크레용 라이브러리를 사용하여 Python 출력에 시각적인 영향을 조금 더 주고 있었는데, 이는 Windows와 Linux 플랫폼 모두에서 작동하기 때문에 유리합니다.하지만 저는 화면에 표시할 뿐만 아니라 로그 파일에 추가할 수도 있었고, 탈출 시퀀스가 로그 파일의 가독성에 영향을 미치고 있었기 때문에 로그 파일을 제거하고 싶었습니다.그러나 크레용으로 삽입된 탈출 시퀀스에서 오류가 발생했습니다.
expected string or bytes-like object
해결책은 매개 변수를 문자열에 캐스팅하여 일반적으로 허용되는 답변에 대한 약간의 수정만 필요했습니다.
def escape_ansi(line):
ansi_escape = re.compile(r'(\x9B|\x1B\[)[0-?]*[ -/]*[@-~]')
return ansi_escape.sub('', str(line))
제거하려면\r\n
비트, 다음 함수를 통해 문자열을 전달할 수 있습니다(sarnold에 의해 작성됨).
def stripEscape(string):
""" Removes all escape sequences from the input string """
delete = ""
i=1
while (i<0x20):
delete += chr(i)
i += 1
t = string.translate(None, delete)
return t
그러나 이렇게 하면 이스케이프 시퀀스 앞과 뒤의 텍스트가 함께 표시됩니다.그래서 마르틴의 필터링된 문자열을 사용하여'ls\r\nexamplefile.zip\r\n'
얻게 될 것입니다lsexamplefile.zip
에 하십시오.ls
원하는 파일 이름 앞에 있습니다.
먼저 stripEscape 함수를 사용하여 이스케이프 시퀀스를 제거한 다음 출력을 Martjn의 정규식으로 전달하여 불필요한 비트가 연결되지 않도록 할 것입니다.
파이썬 3.5를 사용하는 2020년의 경우만큼 쉽습니다.string.encode().decode('ascii')
ascii_string = 'ls\r\n\x1b[00m\x1b[01;31mexamplefile.zip\x1b[00m\r\n\x1b[01;31m'
decoded_string = ascii_string.encode().decode('ascii')
print(decoded_string)
>ls
>examplefile.zip
>
언급URL : https://stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python
'programing' 카테고리의 다른 글
명령줄을 사용하여 Mysql에서 압축된 파일 가져오기 (0) | 2023.08.28 |
---|---|
Mariadb를 위한 Play 2.5 스칼라 구성 (0) | 2023.08.28 |
사용자 지정 헤더를 사용한 AJAX 파일 다운로드 (0) | 2023.08.28 |
신속 - 푸시 알림 배지 번호를 제거하시겠습니까? (0) | 2023.08.28 |
mysql 사용자가 볼륨에 액세스할 수 없는 것 같아 Azure에서 mariadb 컨테이너를 시작할 수 없습니다. (0) | 2023.08.28 |