解析带分隔符的文件并查找列数据类型



是否可以解析带分隔符的文件并找到列数据类型?如

分隔文件:

Email,FirstName,DOB,Age,CreateDate
test@test1.com,Test User1,20/01/2001,24,23/02/2015 14:06:45
test@test2.com,Test User2,14/02/2001,24,23/02/2015 14:06:45
test@test3.com,Test User3,15/01/2001,24,23/02/2015 14:06:45
test@test4.com,Test User4,23/05/2001,24,23/02/2015 14:06:45
输出:

Email datatype: email
FirstName datatype: Text
DOB datatype: date
Age datatype: int
CreateDate datatype: Timestamp

这样做的目的是读取一个带分隔符的文件,动态地构造一个表创建查询,并将数据插入该表。

我尝试使用apache验证器,我认为我们需要解析完整的文件,以确定每个列的数据类型。

编辑:我试过的代码:

CSVReader csvReader = new CSVReader(new FileReader(fileName),',');
String[] row = null;
int[] colLength=(int[]) null;
int colCount = 0;
String[] colDataType = null;
String[] colHeaders = null;
String[] header = csvReader.readNext();
if (header != null) {
    colCount = header.length;
}
colLength = new int[colCount];
colDataType = new String[colCount];
colHeaders = new String[colCount];
for (int i=0;i<colCount;i++){
    colHeaders[i]=header[i];
}
int templength=0;
String tempType = null;
IntegerValidator intValidator = new IntegerValidator();
DateValidator dateValidator = new DateValidator();
TimeValidator timeValidator = new TimeValidator();
while((row = csvReader.readNext()) != null) {
        for(int i=0;i<colCount;i++) {
                templength = row[i].length();
                colLength[i] = templength > colLength[i] ? templength : colLength[i];
                if(colHeaders[i].equalsIgnoreCase("email")){
                        logger.info("Col "+i+" is Email");
                } else if(intValidator.isValid(row[i])){
                        tempType="Integer";
                        logger.info("Col "+i+" is Integer");
                } else if(timeValidator.isValid(row[i])){
                        tempType="Time";
                        logger.info("Col "+i+" is Time");
                } else if(dateValidator.isValid(row[i])){
                        tempType="Date";
                        logger.info("Col "+i+" is Date");
                } else {
                        tempType="Text";
                        logger.info("Col "+i+" is Text");
                }
                logger.info(row[i].length()+"");
        }

不确定这是否是最好的方法,任何指向正确方向的指针都会有所帮助

如果您希望自己编写而不是使用第三方库,那么最简单的机制可能是为每种数据类型定义一个正则表达式,然后检查是否所有字段都满足它。下面是一些示例代码,可以帮助您入门(使用Java 8)。

public enum DataType {
    DATETIME("dd/dd/dddd dd:dd:dd"),
    DATE("dd/dd/dddd",
    EMAIL("\w+@\w+"),
    TEXT(".*");
    private final Predicate<String> tester;
    DateType(String regexp) {
        tester = Pattern.compile(regexp).asPredicate();
    }
    public static Optional<DataType> getTypeOfField(String[] fieldValues) {
        return Arrays.stream(values())
            .filter(dt -> Arrays.stream(fieldValues).allMatch(dt.tester)
            .findFirst();
    }
}

注意,这依赖于枚举值的顺序(例如,测试日期之前的日期)。

是的,这是可能的,你必须首先解析整个文件。为每种数据类型设置一组规则。遍历列中的每一行。从每个列都具有所有数据类型开始,如果列中的某一行违反了该数据类型的规则,则取消该数据类型。在对列进行迭代之后,检查该列的数据类型。如。假设我们有两种数据类型整数和文本…整数规则…它必须只包含数字0-9,并且可以以'-'开头。文本可以是任何内容

列:

345
-1ab
123

整数数据类型将被第二行删除,因此它将是文本。如果第二行是-1那么剩下的将是整数和文本所以它将是整数因为文本永远不会被删除因为我们的规则说文本可以是任何东西。你不需要检查文本如果没有其他数据类型答案就是文本。希望这能回答你的问题

我的项目需要稍微类似的逻辑。搜索了很多,但没有得到正确的解决方案。对我来说,我需要将字符串对象传递给应该返回obj数据类型的方法。最后我找到了@sprinter的帖子,它看起来类似于我的逻辑,但我需要传递字符串而不是字符串数组。

根据我的需要修改了代码并张贴在下面。

public enum DataType {
        DATE("dd/dd/dddd"),
        EMAIL("@gmail"),
        NUMBER("[0-9]+"),
        STRING("^[A-Za-z0-9? ,_-]+$");
        private final String regEx;
        public String getRegEx() {
            return regEx;
        }
        DataType(String regEx) {
            this.regEx = regEx;
        }
        public static Optional<DataType> getTypeOfField(String str) {
            return Arrays.stream(DataType.values())
                .filter(dt -> {
                    return Pattern.compile(dt.getRegEx()).matcher(str).matches();
                 })
                .findFirst();
        }
}
例如:

Optional<DataType> dataType = getTypeOfField("Bharathiraja");
System.out.println(dataType);
System.out.println(dataType .get());
Output:
Optional[STRING]
STRING

请注意,常规的出口图案会根据需求而变化,所以请根据您的需要修改图案,不要接受它。

快乐编码!

最新更新