csv 不使用grep或split从Java中提取特定字符串

yhqotfr8  于 2023-04-09  发布在  Java
关注(0)|答案(2)|浏览(109)

我试图从一个大文件中提取变量和它们的值。这个文件有几千行,可能包含也可能不包含一些值。下面是一个示例文件

student name=james age=13 city=toronto
teacher name=joe age=31 city=chicago
student age=21 city=paris

我尝试使用Java提取变量名及其值。换句话说,我想获得typenameagecity
这是我的Java Pojo

public class MyPOJO {
    private String type;
    private String name;
    private int age;
    private String city;

    public MyPOJO(String type, String name, int age, String city) {
        this.type = type;
        this.name = name;
        this.age = age;
        this.city = city;
    }
    //Getters and setters below
}

我的问题是什么是最好的方法来做到这一点?我不想使用grep,因为这个文件的内容可能会改变。我宁愿使用类似Pojo类的东西来提取值。
我目前的解决方案使用String split,但我正在寻找一种更有效的方法。

public MyPOJO extract(String line){
    String[] split = line.split(" ");
    String type, name, city;
    int age;
    type = split[0];
    for(String s : split){
        if(s.contains("name"){
            name = s.split("=")[1];
        }
        if(s.contains("city"){
            name = s.split("=")[1];
        }
        if(s.contains("age"){
            age = Integer.parseInt(s.split("=")[1]);
        }
    }
}
jm81lzqq

jm81lzqq1#

如果文件的结构不会改变,可以使用正则表达式。

@Test
void parse() {
    String text = """
            student name=james age=13 city=toronto
            teacher name=joe age=31 city=chicago
            student age=21 city=paris
            """;

    String regex = "(student|teacher)\\s+(name=(\\w+)\\s+)?age=(\\d+)\\s+city=(\\w+)";
    Pattern pattern = Pattern.compile(regex);

    List<MyPOJO> pojos = pattern.matcher(text)
            .results()
            .map(match -> new MyPOJO(
                    match.group(1),
                    match.group(3),
                    Integer.parseInt(match.group(4)),
                    match.group(5)
            ))
            .toList();

    System.out.println(pojos);
}

简单地说,这就是正则表达式所寻找的:
(student|teacher)匹配“student”或“teacher”;
\s+匹配一个或多个空白字符;
(name=(\w+)\s+)?是一个可选组,匹配“name=”,后跟一个或多个单词字符,再后跟一个或多个空格字符;
age=(\d+)匹配“age=”后跟一个或多个数字;
你可以在这里阅读更多关于regex的内容:https://www.baeldung.com/regular-expressions-java

a1o7rhls

a1o7rhls2#

如果您可能不使用POJO并将所有值都视为String,那么以下将是一个有效的实现。

public static Map<String, String> extract(String line) {
    Map<String, String> parsedLine = new HashMap<String, String>();
    String[] allTokens = line.split(" ");
    parsedLine.put("type", allTokens[0]);
    for (int index = 1; index < allTokens.length; index++) {
        String[] tokenParts = allTokens[index].split("=");
        parsedLine.put(tokenParts[0], tokenParts[1]);
    }
    return parsedLine;
}

相关问题