读取定长文本文件时如何保留白色space

How to preserve white space when reading fixed length text file

我正在阅读一个 .txt 文件,本质上,它是一个包含行和列的 csv 类型文件,只有列由文字 [space] 字符分隔。每列都有这些字符的预定义长度,如数据定义文件中所给。

下面是我试过的,但是它忽略了白色space。这些数字是我用来区分列的。

function formatTextFile(input){
    var readFile = fileOpen(input,"read");
    var line1 = FileReadLine(readFile);
    var line2 = FileReadLine(readFile);
    line2 = REReplace(line2,"[^(.{7}.{10}.{47}.{34}.{14}.{13}.{15}.{22}.{28}.{18}.{2})]+[ ]", "|", "all");
    return line2;
}

这是输出:

|1. 16-1268|5/2/201|31530|[=12=].00|404|AP 

我想尝试使用 java 来进行字符串格式化。这个我还没想好。

如果列宽固定,为什么还要费心使用正则表达式?考虑以下因素:

<cfscript>

    line = "ab  12  xy 654   +1234    ";
    columnLengths = [4, 4, 3, 6, 1, 8];

    o = readFixedLine(line, columnLengths);

    function readFixedLine(line, columnLengths) {

        var cells = [];
        var offset = 1;

        for (length in columnLengths) {
            cells.add( mid(line, offset, length) );
            offset += length;
        }

        return cells;
    }

    // cells read (the dump doesn't display whitespaces)
    writeDump(o);
    /*
        whitespaces represented as asterisks
        [1] ab**
        [2] 12**
        [3] xy*
        [4] 654***
        [5] +
        [6] 1234****
    */

    // proving that whitespaces are kept
    for (entry in o) {
        writeOutput( len(entry) & "<br>" );
    }
    /*
        4
        4
        3
        6
        1
        8
    */

</cfscript>

mid 函数是故障安全的(在这方面),因此您甚至不必担心空行或缺少列。然而,fileReadLine 修剪尾随空格,所以你在这里运气不好。此时只有 Java 可以提供帮助(使用 StreamBufferedReader 阅读您的文件)。

感谢@Alex 提供了一个很好的解决方案。 Java 是要走的路,他的方法非常实用。我只是想展示我是如何将它实现到构建查询中的。

留下一个列和行的数组,您可以使用 QueryAddColumn 将其放入查询对象中。我不得不弄乱列的长度,但是 java 方法是再次 go.Thanks @Alex.

的方法
function formatTextFile(input){
        var fileReader = createObject("java","java.io.FileReader").init(input);
        var bufferedReader = createObject("java","java.io.BufferedReader").init(fileReader);
        var lineReader = createObject("java","java.io.LineNumberReader").init(bufferedReader);

        var columnLengths = [7,10,47,34,14,13,16,22,75,18,2];
        var rows = ArrayNew(2);
        var line = lineReader.readLine();
        //skip empty lines
        while(!structKeyExists(Local,"line")&&!len(trim(Local.line))){
            line = lineReader.readLine();
        }

        while(isDefined("line")){
            var cells = ArrayNew(1);
            var offset = 1;
            for(var i = 1; i<=ArrayLen(columnLengths); i++){
                cells.add(mid(line,offset,columnLengths[i]));
                offset+=columnLengths[i];
                ArrayAppend(rows[i],cells[i]);
            }
            line = lineReader.readLine();
        }
        return rows;        
    }

(评论太长)

关于原始问题的旁注,白色 space 正被正则表达式删除,而不是 FileReadLine. Though personally I find the 更具可读性 - 技术上它 可以 用正则表达式来完成。

例如,您可以创建一个匹配整行的表达式,并使用多个子表达式来匹配每个字段中所需的字符数。然后使用生成的反向引用创建管道分隔字符串,即 || ....

代码: 使用 CF11 测试

// ^ - starting with
// $ - ending with
// ( ) - subexpression or capturing group
//  - backreference, 1 corresponds to first subexpression
result = REReplace(line1
           ,"^(.{7})(.{10})(.{47})(.{34})(.{14})(.{13})(.{15})(.{22})(.{28})(.{18})(.{2})\s+$"
           , "||||||||||"
        );

示例数据:

A1     B         C                                              D                                 E             F            G              H                     I                           J                 K   
A2     B         C                                              D                                 E             F            G              H                     I                           J                 K   
A3     B         C                                              D                                 E             F            G              H                     I                           J                 K  

如果转储结果,并检查每个字段的 len(),您将看到 spaces 保留。所以问题是原始表达式。

for (currValue in listToArray(line1, "|")) {
    writeOutput("<br>["& len(currValue) &"] "& currValue );
}

结果:

[7 ] A1     |
[10] B         |
[47] C                                              |
[34] D                                 |
[14] E             |
[13] F            |
[15] G              |
[22] H                     |
[28] I                           |
[18] J                 |
[2 ] K |