Java-解析分隔文件并查找列数据类型

Java-解析分隔文件并查找列数据类型,java,Java,是否可以解析带分隔符的文件并查找列数据类型?e、 g 分隔文件: 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 te

是否可以解析带分隔符的文件并查找列数据类型?e、 g

分隔文件:

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
其目的是读取带分隔符的文件,动态构造表创建查询,并将数据插入该表

我尝试使用apachevalidator,我相信我们需要解析完整的文件以确定每个列的数据类型

编辑:我尝试过的代码:

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()+"");
        }
CSVReader CSVReader=new-CSVReader(新文件读取器(文件名),',');
字符串[]行=null;
int[]colLength=(int[])null;
int colCount=0;
字符串[]colDataType=null;
字符串[]colHeaders=null;
String[]header=csvReader.readNext();
if(标题!=null){
colCount=页眉长度;
}
colLength=新整数[colCount];
colDataType=新字符串[colCount];
colHeaders=新字符串[colCount];

对于(int i=0;i是的,这是可能的,并且您必须首先解析整个文件。为每个数据类型设置一组规则。迭代列中的每一行。从每个列都有每个数据类型开始,如果该列中的某一行违反了该数据类型的规则,则取消数据类型。迭代列后,请检查该列中剩下的数据类型或者列。例如,假设我们有两种数据类型integer和text…integer的规则…它必须只包含数字0-9,并且可以以“-”开头。text可以是任何内容

我们的专栏:

345
-1ab
123

整数数据类型将被第二行删除,因此它将是文本。如果第二行仅为-1,那么您将保留整数和文本,因此它将是整数,因为文本将永远不会被删除,因为我们的规则说文本可以是任何内容……您基本上不必检查文本,如果您没有其他数据类型,答案是文本。希望这能回答您的问题

是的,这是可能的,并且您必须首先解析整个文件。为每个数据类型设置一组规则。迭代列中的每一行。从每一列都有每个数据类型开始,如果该列中的某一行违反该数据类型的规则,则取消数据类型。迭代列chec后k列的数据类型是什么。例如,假设我们有两种数据类型integer和text…integer的规则…它必须只包含数字0-9,并且可以以“-”开头。text可以是任何内容

我们的专栏:

345
-1ab
123

整数数据类型将被第二行删除,因此它将是文本。如果第二行仅为-1,那么您将保留整数和文本,因此它将是整数,因为文本将永远不会被删除,因为我们的规则说文本可以是任何内容……您基本上不必检查文本,如果您没有其他数据类型,答案是文本。希望这能回答您的问题

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

公共枚举数据类型{
日期时间(“dd/dd/dddd:dd:dd”),
日期(“dd/dd/dddd”,
电子邮件(“\\w+@\\w+”,
文本(“.”);
专用最终谓词测试器;
日期类型(字符串regexp){
tester=Pattern.compile(regexp.asPredicate();
}
公共静态可选getTypeOfField(字符串[]字段值){
返回Arrays.stream(values())
.filter(dt->Arrays.stream(fieldValues).allMatch(dt.tester)
.findFirst();
}
}

请注意,这取决于枚举值的顺序(例如,在日期之前测试日期时间).

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

公共枚举数据类型{
日期时间(“dd/dd/dddd:dd:dd”),
日期(“dd/dd/dddd”,
电子邮件(“\\w+@\\w+”,
文本(“.”);
专用最终谓词测试器;
日期类型(字符串regexp){
tester=Pattern.compile(regexp.asPredicate();
}
公共静态可选getTypeOfField(字符串[]字段值){
返回Arrays.stream(values())
.filter(dt->Arrays.stream(fieldValues).allMatch(dt.tester)
.findFirst();
}
}

请注意,这取决于枚举值的顺序(例如,在日期之前测试日期时间).

我的项目需要类似的逻辑。搜索了很多,但没有得到正确的解决方案。对我来说,我需要将string对象传递给应该返回obj的数据类型的方法。

最后我从@sprinter找到了帖子,它看起来与我的逻辑相似,但我需要传递string而不是string数组

根据我的需要修改了代码并发布在下面

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();
        }
}
公共枚举数据类型{
日期(“dd/dd/dddd”),
电邮(“@gmail”),
编号(“[0-9]+”),
字符串(“^[A-Za-z0-9?,-]+$”;
私有最终字符串正则表达式;
公共字符串getRegEx(){
返回正则表达式;
}
数据类型(字符串正则表达式){
this.regEx=regEx;
}
公共静态可选getTypeOfField(字符串str){
返回Arrays.stream(DataType.values())
.过滤器(dt->{
返回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
可选数据类型=getTypeOfField(“Bharathiraja”);
System.out.println(数据类型);
System.out.println(dataType.get());
输出:
可选[字符串]
一串
请注意,常规exp模式因需求而异,因此根据需要修改模式,而不是照原样


愉快的编码!

我的项目需要类似的逻辑。搜索了很多,但没有得到正确的解决方案。对我来说,我需要将string对象传递给应该返回obj的数据类型的方法。.final