当前位置: 首页 > 知识库问答 >
问题:

Univocity——如何将3(n)行解析为一行(bean)

长孙逸仙
2023-03-14

我正在为我的一个项目评估Univocity解析器,固定宽度平面文件格式从三个细节记录(例如,以AA、BB、CC开头)生成一个记录(Bean)——这个文件可以使用Univocity解析吗
我可以使用recordEndsOnNewline继续阅读并添加一些自定义转换,但是是否有现成的ParserSettings

AA1234 data
BBmore data
CCsome more data row 1 ended
AA5678 data
BBmore data
CCsome more data row 2 ended

更新:

可以使用:setLine分离器("\nAA");

共有1个答案

孟豪
2023-03-14

这里是图书馆的作者。首先需要定义字段位置。当你想解析出现在多行中的值时,你必须将recordEndsOnNewLine设置为false,这样你的思路就对了。

如果你加入形成一个记录的行,就更容易“看到”每个记录的开始和结束:

String input = "" +
    "AA1234 data\nBBmore data\nCCsome more data row 1 ended\n" +
    "AA5678 data\nBBmore data\nCCsome more data row 2 ended";

根据您提供的示例,可以创建以下字段配置(我假设您不需要“AA”、“BB”和“CC”字符串):

FixedWidthFields fields = new FixedWidthFields();
fields
        .addField("a1", 2, 6)
        .addField("a2", 7, 11)
        .addField("b1", 14, 23)
        .addField("c1", 26, 40)
        .addField("c2", 41, 52);

你可以用这个解析你的输入:

FixedWidthParserSettings settings = new FixedWidthParserSettings(fields);
settings.getFormat().setLineSeparator("\n");
settings.setRecordEndsOnNewline(false);

FixedWidthParser parser = new FixedWidthParser(settings);

List<String[]> rows = parser.parseAll(new StringReader(input));
for (String[] row : rows) {
    System.out.println(Arrays.toString(row));
}

这将给你正确的输出:

[1234, data, more data, some more data, row 1 ended]
[5678, data, more data, some more data, row 2 ended]

现在我们知道了每个字段的起点和终点,我们可以定义您的java bean:

public static class Bean {
    @FixedWidth(from = 2, to = 6)
    @Parsed
    int a1;

    @FixedWidth(from = 7, to = 11)
    @Parsed
    String a2;

    @FixedWidth(from = 14, to = 23)
    @Parsed
    String b1;

    @FixedWidth(from = 26, to = 40)
    @Parsed
    String c1;

    @FixedWidth(from = 41, to = 52)
    @Parsed
    String c2;

    @Override
    public String toString() {
        return "Bean{" +
                "a1=" + a1 +
                ", a2='" + a2 + '\'' +
                ", b1='" + b1 + '\'' +
                ", c1='" + c1 + '\'' +
                ", c2='" + c2 + '\'' +
                '}';
    }
}

这样一来,解析输入就变得简单了:

FixedWidthParserSettings settings = new FixedWidthParserSettings();
settings.getFormat().setLineSeparator("\n");
settings.setRecordEndsOnNewline(false);
settings.setHeaderExtractionEnabled(false); // This one is important as your input has no headers.

FixedWidthRoutines routines = new FixedWidthRoutines(settings);
for(Bean bean : routines.parseAll(Bean.class, new StringReader(input))){
    System.out.println(bean);
}

它会像这样将bean打印到输出:

Bean{a1=1234, a2='data', b1='more data', c1='some more data', c2='row 1 ended'}
Bean{a1=5678, a2='data', b1='more data', c1='some more data', c2='row 2 ended'}

希望这有帮助

 类似资料:
  • 是否可以根据索引范围将一行解析为多个bean 例: 行:“字段1”、“字段2”、“字段3”。。。。,“字段9”

  • 我试图使用univocity解析器将csv文件解析为bean的新实例和现有实例。csv是通过使用univocity BeanWriterProcessor生成的,对于我将称为set a的一组bean。 现在我想读回csv,执行以下操作: 案例1:如果行对应于最初出现在集合a中的一个bean,我不想创建一个新的bean实例,而是将csv读入“现有”实例。(即,“更新”实例)。我通过使用bean的UU

  • 我正在尝试从GTFS读取CSV文件。在uniVocity解析器的帮助下压缩,遇到了一个我无法解决的问题。出于某种原因,某些CSV文件的第一列似乎无法正确解析。例如,在“stops.txt”文件中,如下所示: 无法正确解析“stop_id”字段,该字段的值为“null” 这是我用来读取文件的方法: 这就是我的Stop课程的样子: 如果我调用的方法,我得到这个输出是不正确的: 输出: 有人知道为什么会

  • 我有一个这样的表,我想解析它以获得和表的第二列和第三列。 我想打印出来。 我尝试了这个线程中的以下建议,但没有选择如何使用jsoup从HTML解析表 编辑:也尝试使用Jsoup.connect()代替parse()

  • 我有一个文件,它有固定的行,但每一行都映射到不同的Java类。 例如 对于第一排,我有后续类: 第二排我有: 我想将TSV文件直接解析到相应的对象,但我没有什么想法。

  • 我试图使用统一解析器来解析一个固定宽度格式的文件,该文件每行包含可变数量的固定宽度记录。 格式为记录id[6],子记录[3]的#,子记录[6] 期望的结果是有一个子记录数组。@链接注释似乎适用,但留档声明这仅适用于超文本标记语言解析器。 我目前的解决方案是将子记录解析为字符串,然后循环遍历每个记录,并在子记录字符串中插入换行符,然后重新解析。有没有一种方法可以使用univocity解析器来实现这一