我从大量相当随机的shell进程接收管道stdout输出,所有这些都作为单个node.js进程的输入(stdin)。对于调试和解析,我需要处理通过管道传输到进程中的不同特殊字符代码。它确实可以帮助我看到隐形字符(主要用于调试),并在我确定使用它们的模式后相应地处理它们。
给定带有ANSI特殊字符\u001b*
的javascript字符串和/或\n
,\t
,\r
等元字符,如何显示这些特殊字符它们实际上并未被渲染,而是作为代码值公开。
例如,假设我在绿色中打印了以下字符串(无法在SO上显示绿色):
This is a string.
We are now using the green color.
我希望能够对此字符串执行console.log
(例如),并使用ANSI代码替换非打印字符,元字符/换行符,颜色代码等:
"\u001b[32m\tThis is a string.\nWe are now using the green color.\n"
我可以做类似以下的事情,但它太具体,硬编码,效率低下:
line = line.replace(/[\f]/g, '\\n');
line = line.replace(/\u0008/g, '\\b');
line = line.replace(/\u001b|\u001B/g, '\\u001b');
line = line.replace(/\r\n|\r|\n/g, '\\n');
...
答案 0 :(得分:2)
试试这个:
var map = { // Special characters
'\\': '\\',
'\n': 'n',
'\r': 'r',
'\t': 't'
};
str = str.replace(/[\\\n\r\t]/g, function(i) {
return '\\'+map[i];
});
str = str.replace(/[^ -~]/g, function(i){
return '\\u'+("000" + i.charCodeAt(0).toString(16)).slice(-4);
});
答案 1 :(得分:1)
这是一个循环遍历字符串的版本,测试它是否是一个普通的可打印字符,如果不是,则在一个特殊的表中查找它,以便您自己表示该字符,如果在表中找不到,则显示任何内容您想要的默认表示:
var tagKeys = {
'\n': 'New Line \n',
'\u0009': 'Tab',
'\u2029': 'Line Separator'
/* and so on */
};
function tagSpecialChars(str) {
var output = "", ch, replacement;
for (var i = 0; i < str.length; i++) {
ch = str.charAt(i);
if (ch < ' ' || ch > '~') {
replacement = tagKeys[ch];
if (replacement) {
ch = replacement;
} else {
// default value
// could also use charCodeAt() to get the numeric value
ch = '*****';
}
}
output += ch;
}
return output;
}
演示:http://jsfiddle.net/jfriend00/bCYa4/
这显然不是一些花哨的正则表达式解决方案,但是你说性能很重要,你很少使用正则表达式找到性能最佳的操作,当然如果你要使用它们中的一大堆那么。此外,每个正则表达式替换都必须遍历整个字符串。
这个类似工人的解决方案只是在输入字符串中循环一次,并允许您自定义所需的任何不可打印字符的显示转换,并确定当您不是可打印字符时要显示的内容有一个特殊的显示表示。