node子进程返回数据带ANSI编码
什么是ANSI?
这里得说明下ANSI在终端内的作用,ANSI转义序列是一种带内信号的转义序列标准,用于控制视频文本终端上的光标位置、颜色和其他选项。在文本中嵌入确定的字节序列,大部分以ESC转义字符和"["字符开始,终端会把这些字节序列解释为相应的指令,而不是普通的字符编码。
就是说node输出给我们的字符串本来是要在终端内展示的,而且这里是带格式的,例如错误的标红,换行,清屏等等。下面就是带ANSI的字符串:
这里有用的信息其实只有
File "test.py", line 2
pythonEditor.vue?aa11:652
SyntaxError: invalid syntax
里有一些奇怪字符·[2等等,这些就是ASNI的控制字符
这里的点就是ESC的意思,其中我发现有一个是ESC]的奇怪字符,这里的中括号和其它事反的,通过终端发现ESC]后面的字符到下个控制命令之间的字符都会被忽略。就是“C:UsersadminAppDataLocalProgramscodesprite-test
esourcesappdistelectronstaticPython3python.exe”这段是不需要的。
知道了这些我们就可以进行处理了,先找到获取ANSI的正则。
const ansiRegex = ({onlyFirst = false} = {}) => {
const pattern = [
'[\u001B\u009B][[\]()#;?]*(?:(?:(?:[a-zA-Z\d]*(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?\u0007)',
'(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-ntqry=><~]))'
].join('|');
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}
通过正则可以将字符内所有ANSI字符匹配出来,然后将其删除,再特殊处理ESC]后面的字符串
function filter (text) {
const arr = text.match(ansiRegex())
arr.forEach((ele, idx) => {
if (ele.includes(']')) {
const _idx = text.indexOf(ele)
if (idx !== arr.length - 1) {
const next = arr[idx + 1]
const _idx2 = text.indexOf(next) + next.length
const as=text.slice(_idx, _idx2)
text = text.replace(as, '')
} else {
const as = text.slice(_idx, text.length - 1)
text = text.replace(as, '')
}
}
text = text.replace(ele, '')
})
return text
}
这个就是简单的处理ansi字符的方法了。