在Javascript字符串中显示所有非打印ANSI字符和元字符

时间:2014-06-16 20:28:18

标签: javascript regex string

我从大量相当随机的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');
...

2 个答案:

答案 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/

这显然不是一些花哨的正则表达式解决方案,但是你说性能很重要,你很少使用正则表达式找到性能最佳的操作,当然如果你要使用它们中的一大堆那么。此外,每个正则表达式替换都必须遍历整个字符串。

这个类似工人的解决方案只是在输入字符串中循环一次,并允许您自定义所需的任何不可打印字符的显示转换,并确定当您不是可打印字符时要显示的内容有一个特殊的显示表示。