当文本可以有非拉丁字母时,如何计算字符长度

时间:2016-11-29 14:29:20

标签: javascript unicode

我有以等宽字体显示ASCII表的功能

        function ascii_table(array, header) {
            if (!array.length) {
                return '';
            }

            for (var i = array.length - 1; i >= 0; i--) {
                var row = array[i];
                var stacks = [];
                for (var j = 0; j < row.length; j++) {
                    var new_lines = row[j].toString().split("\n");
                    row[j] = new_lines.shift();
                    stacks.push(new_lines);
                }
                var new_rows_count = Math.max.apply(Math, stacks.map(function(column) {
                    return column.length;
                }));
                for (var k = new_rows_count - 1; k >= 0; k--) {
                    array.splice(i + 1, 0, stacks.map(function(column) {
                        return column[k] || "";
                    }));
                }
            }

            var lengths = array[0].map(function(_, i) {
                var col = array.map(function(row) {
                    if (row[i] != undefined) {
                        return row[i].length;
                    } else {
                        return 0;
                    }
                });
                return Math.max.apply(Math, col);
            });
            // column padding
            array = array.map(function(row) {
                return '| ' + row.map(function(item, i) {
                    var size = item.length;
                    if (size < lengths[i]) {
                        if (item.match(/\t/g)) {
                            // tab have 4 spaces
                            size += item.match(/\t/g).length*3;
                        }
                        item += new Array(lengths[i] - size + 1).join(' ');
                    }
                    return item;
                }).join(' | ') + ' |';
            });
            var sep = '+' + lengths.map(function(length) {
                return new Array(length + 3).join('-');
            }).join('+') + '+';
            if (header) {
                return sep + '\n' + array[0] + '\n' + sep + '\n' +
                    array.slice(1).join('\n') + '\n' + sep;
            } else {
                return sep + '\n' + array.join('\n') + '\n' + sep;
            }
        }

但如果一个字符宽度为两个ascii字母,表格单元格包含中文之类的日文字母,则会失败:

中文
rock

我该如何处理这样的案件?如何知道角色的宽度是否大小为2?

1 个答案:

答案 0 :(得分:1)

您需要检查字符 width 而不是长度。任何({体面的)port wcwidth都可以做到这一点。