用例是在使用Angular9构建的UI中显示服务器日志。我正在使用ACE编辑器显示通过HTTP调用从服务器接收到的文本内容,并且服务器以最近的1000行日志作为响应为了验证内容,我做了console.log()来查看chrome dev工具中的文本内容。Console output received from server
在将相同内容加载到编辑器时,我注意到特殊字符
Ace editor content while using in text mode
附有2张截图进行比较
HTML内容
<div ace-editor #codeEditor style="min-height: 550px; width:100%; overflow: auto;"></div>
打字稿
import { Component, ViewChild, ElementRef, Input, SimpleChanges } from '@angular/core';
import * as ace from 'ace-builds';
import 'ace-builds/src-noconflict/mode-json';
import 'ace-builds/src-noconflict/theme-github';
import 'ace-builds/src-noconflict/ext-beautify';
const THEME = 'ace/theme/github';
const LANG = 'ace/mode/text';
@Component({
selector: 'app-text-editor',
templateUrl: './text-editor.component.html',
styleUrls: ['./text-editor.component.css']
})
export class TextEditorComponent {
@ViewChild('codeEditor') codeEditorElmRef: ElementRef;
private codeEditor: ace.Ace.Editor;
@Input() textObject;
@Input() readMode;
data: any;
mode: any;
constructor() { }
ngOnChanges(changes: SimpleChanges) {
for (const properties of Object.keys(changes)) {
if (properties == 'textObject') {
const currentJSONObject = changes[properties];
if (currentJSONObject.currentValue && currentJSONObject.firstChange == false)
this.codeEditor.setValue(currentJSONObject.currentValue, -1);
else
this.data = currentJSONObject.currentValue
}
if (properties == 'readMode') {
const currentReadMode = changes[properties];
if (currentReadMode.firstChange == false)
this.codeEditor.setReadOnly(currentReadMode.currentValue);
else
this.mode = currentReadMode.currentValue
}
}
}
ngAfterViewInit() {
const element = this.codeEditorElmRef.nativeElement;
const editorOptions: Partial<ace.Ace.EditorOptions> = {
highlightActiveLine: true,
displayIndentGuides: true,
highlightSelectedWord: true,
};
this.codeEditor = ace.edit(element, editorOptions);
this.codeEditor.setTheme(THEME);
this.codeEditor.getSession().setMode(LANG);
this.codeEditor.setShowFoldWidgets(true);
this.codeEditor.setHighlightActiveLine(true);
this.codeEditor.setShowPrintMargin(false);
this.codeEditor.setReadOnly(this.readMode);
this.codeEditor.navigateFileEnd();
if (this.data)
this.codeEditor.setValue(this.data, - 1);
if (this.mode)
this.codeEditor.setReadOnly(this.mode);
}
}
这不是ace添加的字符,而是终端发送的颜色控制字符。如果您不想显示颜色,而只希望文本使用以下功能
var CSIRegexp;
function getCSIRegexp() {
if (CSIRegexp) return CSIRegexp;
// http://www.inwap.com/pdp10/ansicode.txt
var classes = {
C0 : "\\x00-\\x1F", //
SPACE : "\\x20\\xA0" , // Always and everywhere a blank space
G0 : "\\x21-\\x7E", //
Intermediate : "\\x20-\\x2F", // !"#$%&'()*+,-./
Parameters : "\\x30-\\x3F", // 0123456789:;<=>?
Uppercase : "\\x40-\\x5F", // @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
Lowercase : "\\x60-\\x7E", // `abcdefghijlkmnopqrstuvwxyz{|}~
Alphabetic : "\\x40-\\x7E", // (all of upper and lower case)
Delete : "\\x7F" , // Always and everywhere ignored
C1 : "\\x80-\\x9F", // 32 additional control characters
G1 : "\\xA1-\\xFE", // 94 additional displayable characters
Special : "\\xA0\\xFF" , // Same as SPACE and DELETE
ESC : "\\x1b" , //
Ignore : "\\x7F\\x00-\\x1F\\x80-\\x9F" // Delete|C0|C1
};
var g = /:ESC:(\[:Parameters:*:Intermediate:?:Alphabetic:?|:Intermediate:+:Parameters:|:Parameters:|:Lowercase:|)|[:Ignore:]/;
var inBrackets = false;
var source = g.source.replace(/(\\.)|([\[\]])|:(\w*):/g, function(_, esc, b, cls) {
if (esc) return esc;
if (b) {
inBrackets = b == "[";
return b;
}
if (!cls) return ":";
var r = classes[cls];
if (!/ESC|Delete|C0|C1/.test(cls)) {
r += classes.Ignore;
}
if (!inBrackets && cls != "ESC")
r = "[" + r + "]";
return r;
});
return CSIRegexp = new RegExp(source, "g");
}
在将数据设置到编辑器之前删除控制字符
this.codeEditor.setValue(this.data.replace(getCSIRegexp(), ""), - 1);
您可以通过以下电话进行测试:
"\x1b[1mreal text\x1b[10m".replace(getCSIRegexp(), "")