实现功能: 编写一个自定义的监听器,将逗号分隔符文件(csv)中的数据加载到一种数据结构--“由Map组成的List”中。
antlr4文件:
grammar CSV; file : hdr row+ ; hdr : row ; row : field (',' field)* ' '? ' ' ; field : TEXT # text | STRING # string | # empty ; TEXT : ~[, "]+ ; STRING : '"' ('""'|~'"')* '"' ;
LoadCSV.java 文件:
import org.antlr.v4.runtime.CharStream; import org.antlr.v4.runtime.CharStreams; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.tree.ParseTreeWalker; import java.io.*; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; class Loader extends CSVBaseListener { public static final String EMPTY = ""; /** * Load a list of row maps that map field name to value */ List<Map<String, String>> rows = new ArrayList<Map<String, String>>(); /** * List of column names */ List<String> header; /** * Build up a list of fields in current row */ List<String> currentRowFieldValues; public void exitString(CSVParser.StringContext ctx) { currentRowFieldValues.add(ctx.STRING().getText()); } public void exitText(CSVParser.TextContext ctx) { currentRowFieldValues.add(ctx.TEXT().getText()); } public void exitEmpty(CSVParser.EmptyContext ctx) { currentRowFieldValues.add(EMPTY); } public void exitHdr(CSVParser.HdrContext ctx) { header = new ArrayList<String>(); header.addAll(currentRowFieldValues); } public void enterRow(CSVParser.RowContext ctx) { currentRowFieldValues = new ArrayList<String>(); } public void exitRow(CSVParser.RowContext ctx) { // If this is the header row, do nothing // if ( ctx.parent instanceof CSVParser.HdrContext ) return; OR: if ( ctx.getParent().getRuleIndex() == CSVParser.RULE_hdr ) return; // It's a data row Map<String, String> m = new LinkedHashMap<String, String>(); int i = 0; for (String v : currentRowFieldValues) { m.put(header.get(i), v); i++; } rows.add(m); } } public class LoadCSV { public static void main(String[] args) throws IOException { /* 新的版本已经抛弃 File csvFile = new File("F:\IDEA_JAVA\CSV\test\test.csv"); InputStream fi = new FileInputStream(csvFile); ANTLRInputStream inputStream = new ANTLRInputStream(fi); CSVLexer lexer = new CSVLexer(inputStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); CSVParser parser = new CSVParser(tokenStream); ParseTreeWalker walker = new ParseTreeWalker(); Loader loader = new Loader(); walker.walk(loader, parser.file()); System.out.println(loader.rows); */ String path = "F:\IDEA_JAVA\CSV\test\test.csv"; CharStream inputStream = CharStreams.fromFileName(path); CSVLexer lexer = new CSVLexer(inputStream); CommonTokenStream tokenStream = new CommonTokenStream(lexer); CSVParser parser = new CSVParser(tokenStream); ParseTreeWalker walker = new ParseTreeWalker(); Loader loader = new Loader(); walker.walk(loader, parser.file()); System.out.println(loader.rows); } }
提取码:i4xh