在不使用 grep 或 split 的情况下从 Java 中提取特定字符串

问题描述 投票:0回答:2

我正在尝试从一个大文件中提取变量及其值。 该文件有数千行,可能包含也可能不包含某些值。这是一个示例文件

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

我正在尝试使用 Java 提取变量名称及其值。换句话说,我想得到

type
name
age
city

这是我的 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]);
        }
    }
}
java csv extract text-extraction
2个回答
0
投票

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

@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)
匹配“学生”或“老师”;

\s+
匹配一个或多个空白字符;

(name=(\w+)\s+)?
是一个可选组,匹配“name=”后跟一个或多个单词字符,后跟一个或多个空白字符;

age=(\d+)
匹配“age=”后跟一位或多位数字;

您可以在此处阅读有关正则表达式的更多信息:https://www.baeldung.com/regular-expressions-java


0
投票

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

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;
}
© www.soinside.com 2019 - 2024. All rights reserved.