阅读固定长度文本文件时如何保留空白区

时间:2016-06-17 20:29:10

标签: coldfusion whitespace readfile

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

Sample of Text File

以下是我尝试过的内容,但它忽略了空格。这些数字是我给你区分列的原因。

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|$0.00|404|AP 

我考虑过尝试使用java来进行字符串格式化。我还没想出来。

3 个答案:

答案 0 :(得分:2)

感谢@Alex提供了一个出色的解决方案。 Java是可行的方法,他的方法非常实用。我只是想表明我是如何实现它来构建查询的。

左侧有一个列和行数组,您可以将它们放入QueryAddColumn的查询对象中。我不得不搞乱列长,但java方法是要走的路。再次感谢@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;        
    }

Image of the output

答案 1 :(得分:1)

如果你有固定的列宽,为什么还要打扰正则表达式呢?请考虑以下事项:

private static Func<DatabaseDataContext, DateTime, Staff_Time_TBL>
    queryFor =
    CompiledQuery.Compile((DatabaseDataContext db, DateTime dDate) =>
    db.Staff_Time_TBLs.Where(a => a.Date_Data == dDate &&
    a.Time_Data_1 == null && a.Time_Data_2 == null).FirstOrDefault());    

<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修剪尾随空格,所以你在这里运气不好。此时只有Java可以提供帮助(使用fileReadLineStream读取您的文件。)

答案 2 :(得分:1)

(评论太长)

关于原始问题的旁注,正空表格正在删除空格,而不是FileReadLine。虽然我个人认为other approaches更具可读性 - 但从技术上来说,可以使用正则表达式完成。

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

代码: 使用CF11进行测试

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

示例数据:

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(),您将看到 的空格被保留。所以问题是原始表达。

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 |