java - 如何将具有不同字段计数的分隔文本行解析为对象,同时允许扩展?

标签 java string parsing

例子如下:

SEG1|asdasd|20111212|asdsad
SEG2|asdasd|asdasd
SEG3|sdfsdf|sdfsdf|sdfsdf|sdfsfsdf
SEG4|sdfsfs|

基本上,每个 SEG* 行都需要解析为相应的对象,定义每个字段的内容。一些,例如 SEG1 中的第三个字段将被解析为 Date

每个对象通常会保持不变,但在某些情况下可能会添加额外的字段,如下所示:

SEG1|asdasd|20111212|asdsad|12334455

目前,我正在考虑使用以下类型的算法:

List<String> segments = Arrays.asList(string.split("\r"); // Will always be a CR.
List<String> fields;
String fieldName;
for (String segment : segments) {
    fields = Arrays.asList(segment.split("\\|");
    fieldName = fields.get(0);
    SEG1 seg1;
    if (fieldName.compareTo("SEG1") == 0) {
        seg1 = new Seg1();
        seg1.setField1(fields.get(1));
        seg1.setField2(fields.get(2));
        seg1.setField3(fields.get(3));
    } else if (fieldName.compareTo("SEG2") == 0) {
        ...
    } else if (fieldName.compareTo("SEG3") == 0) {
        ...
    } else {
        // Erroneous/failure case.
    }
}

某些字段也可能是可选的,具体取决于要填充的对象。我担心的是,如果我向类中添加新字段,则还需要更新任何使用期望字段计数的检查。我该如何着手解析行,同时允许在类对象中填充新的或修改的字段类型?

最佳答案

如果您可以为所有要解析的类定义一个通用接口(interface),我建议如下:

interface Segment {}

class SEG1 implements Segment
{
    void setField1(final String field){};
    void setField2(final String field){};
    void setField3(final String field){};
}

enum Parser {
    SEGMENT1("SEG1") {
        @Override
        protected Segment parse(final String[] fields)
        {
            final SEG1 segment = new SEG1();
            segment.setField1(fields[0]);
            segment.setField1(fields[1]);
            segment.setField1(fields[2]);
            return segment;
        }
    },        
    ...
    ;

    private final String name;

    private Parser(final String name)
    {
        this.name = name;
    }

    protected abstract Segment parse(String[] fields);

    public static Segment parse(final String segment)
    {
        final int firstSeparator = segment.indexOf('|');

        final String name = segment.substring(0, firstSeparator);
        final String[] fields = segment.substring(firstSeparator + 1).split("\\|");

        for (final Parser parser : values())
            if (parser.name.equals(name))
                return parser.parse(fields);

        return null;
    }
}

对于每种类型的段,将一个元素添加到枚举中,并在 parse(String[]) 方法中处理不同类型的字段。

关于java - 如何将具有不同字段计数的分隔文本行解析为对象,同时允许扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8395641/

相关文章:

java - 使用 JavaMail 发送带有附件的邮件 - 写入 Multipart 时出现异常

java - primefaces ajax 从另一种形式更新面板

java - "MediaType.APPLICATION_JSON"和 "application/json"有什么区别

c++ - 计算字符串 vector 中出现的次数

java - Java 中的线程安全映射

java - 正则表达式:删除 Java 中的第二对括号

java - 验证字符串是否精确为 "kind"(java)

string - 如何在同一规则中混合字符串解析和 block 解析?

c++ - 如何使用 spirit x3 将结果解析结果移动到结构中

python - 用于解析包含 'v.' 的标题的 pyparsing 语法