带空格的字符串解析

时间:2019-08-12 09:21:22

标签: java string split

我正在读取一个文件,每个文件看起来像这样:

EmpId:6428 EmpName:Josh Classes:[Math, English, Bio, Art, comp]

我想要EmpIdEmpName和班级。我将其按空间拆分,这反过来也拆分了类。因此,基本上在课程列表的最后,我只是得到Classes:[Math,。但是我想要整个课程清单。请分享您对如何拆分的建议。谢谢

private static class EmpResource {
        private String empId;
        private String empName;
        private List<String> classes;

        public TableResource(final String line) {
            String[] strs = line.split(" ");
            this.empId = strs[0].split(":")[1];
            this.empName = strs[1].split(":")[1];
            String classes = strs[2].split(":")[1];
            convertToClassList(classes);
        }


        void setClasses(List<String> classes) {
            this.classes = classes;
        }


        private void convertToClassList(String classes) {

            if (!"null".equals(class)) {
                String replace = indexString.replaceAll("^\\[|]$", "");
                setIndexes(new ArrayList<>(Arrays.asList(replace.split(", "))));
            }
        }
    }

预期结果:

empId 6428
empName Josh 
List<String> classes [Math,English,Bio,Art,comp]

实际结果:

empId 6428
empName Josh
List<String> classes [Math,

4 个答案:

答案 0 :(得分:1)

如评论中所述,一个有效的但肮脏的解决方案是不对内部空格分隔的“类”元素进行拆分,这将使初始拆分的条件是在空格之前没有逗号。

例如,仅当空格前面没有逗号时,才可以使用负向后分割。

示例

String test = "EmpId:6428 EmpName:Josh Classes:[Math, English, Bio, Art, comp]";
System.out.println(test.split("(?<!,) ")[2]);

输出

Classes:[Math, English, Bio, Art, comp]

尽管如此,通常来说,如果语法变得更复杂,您可能要考虑实现自己的解析器。

正则表达式只能在反向触发之前将您带走。

答案 1 :(得分:1)

使用String.split with a limit

然后,您仅将行分成3个字符串,因此所有类都将放在最后一个字符串中。

String line = "EmpId:6428 EmpName:Josh Classes:[Math, English, Bio, Art, comp]";
String[] strs = line.split(" ", 3);
System.out.println(strs[2]);

输出:

Classes:[Math, English, Bio, Art, comp]

正如FedericoklezCulloca在评论中指出的那样,如果名称中包含空格(例如名字,姓氏),则上述方法将无效。一种更健壮的方法是查找特定标签,如以下使用正则表达式进行编码的代码所示:

private static Pattern LINE_PATTERN =
        Pattern.compile("EmpId:(.*) EmpName:(.*) Classes:\\[(.*)\\]");

public void test() {
    String line = "EmpId:6428 EmpName:Josh Adams Classes:[Math, English, Bio, Art, comp]";
    Matcher lineMatcher = LINE_PATTERN.matcher(line);
    if (lineMatcher.matches()) {
        System.out.println("EmpId   = " + lineMatcher.group(1));
        System.out.println("Name    = " + lineMatcher.group(2));
        System.out.println("Classes = " + lineMatcher.group(3));
    }
}

输出:

EmpId   = 6428
Name    = Josh Adams
Classes = Math, English, Bio, Art, comp

答案 2 :(得分:1)

显然您知道您有empId,empName和Classes部分,所以为什么不使用与整行匹配的单个正则表达式:

public static void main(String[] args) {
    Pattern p=Pattern.compile("EmpId:(.*) EmpName:(.*) Classes:\\[(.*)\\]");
    String input="EmpId:6428 EmpName:Josh Classes:[Math, English, Bio, Art, comp]";
    Matcher m=p.matcher(input);
    if(m.matches())
    {
        System.out.println("empId:"+m.group(1));
        System.out.println("empName"+m.group(2));
        System.out.println("Classes:"+m.group(3));
        String[] classes=m.group(3).split(", ");
        System.out.println("classes:'"+classes[1]+"'");

    } else
        System.err.println("no match");
}

答案 3 :(得分:0)

如果行不是最后一行,则可以执行line = line.replaceAll(", ", "");,但是因为它是临时字符串,所以需要这样做。

String temp = String.valueOf(line.toCharArray().clone());
temp = temp.replaceAll(", ", "");

然后,您将可以做任何事而没有任何麻烦,因为没有其他空间可以干扰。

String[] strs = temp.split(" "); // Make sure it's temp, since temp is the one you changed.
this.empId = strs[0].split(":")[1];
this.empName = strs[1].split(":")[1];
String classes = strs[2].split(":")[1];
convertToClassList(classes);
相关问题