【问题标题】:How to read csv-input using named groups in java?java - 如何在java中使用命名组读取csv输入?
【发布时间】:2014-09-10 09:48:22
【问题描述】:

我目前正在开发一个从 csv 文件获取输入的程序。 这个输入的结构是众所周知的。我想使用正则表达式读取文件。虽然我知道正则表达式,但我很少使用它们,我想我犯了一些简单的错误......

我为您创建了一个代码存根。

前两行是我的“真实”演示输入和相应的正则表达式,它不起作用。每行包含一个 ID、一个名称、一个布尔属性(1 或 0)和对父节点的引用。

下面是我的“训练”演示输入和正则表达式。我剥离了除 id 之外的所有内容。

扫描仪永远不会匹配我的LINEPATTERN。我想获取组值也会有问题......

感谢任何帮助

//  private final static String DEMOINPUT = "0,ROOT,1,null\n1,NODE1,1,0\n2,NODE2,0,0";
//  private final static String LINEREGEX = "(?<id>\\d+),(?<name>\\w+),(?<active>[01]),(?<predecessor>[\\d+|(null)])";

private final static String DEMOINPUT = "0\n1\n2";
private final static String LINEREGEX = "(?<id>\\d+)";

private final static Pattern LINEPATTERN = Pattern.compile(LINEREGEX);

private ElementComponent root = null;
private String input;

public StringInputTransformer() {
    input = DEMOINPUT;
    map();
}

private void map() {
    try (Scanner sc = new Scanner(input)) {
        sc.useDelimiter(",\\n");
        while (sc.hasNext(LINEPATTERN)) {
            String nextLine = sc.next(LINEREGEX);
            Matcher matcher = LINEPATTERN.matcher(nextLine);

            int id = Integer.parseInt(matcher.group("id"));
            String name = matcher.group("name");
            String activeString = matcher.group("active");
            String preId = matcher.group("predecessor");

            Boolean active = "1".equals(activeString) ? true : false;
            ElementComponent element = new ElementComponent(id, name, active);
            if ("null".equals(preId)) {
                this.root = element;
            } else {
                handleNonRoot(element);
            }

        }
    }
}

【问题讨论】:

  • 自己实现 csv 阅读器有什么特别的原因吗?您可以找到许多非常有效地做到这一点的第三方
  • 我想到了这一点,但我再次认为这将是训练正则表达式的好机会。如您所见,这确实是必要的。

标签: java regex csv


【解决方案1】:

[\d+|(null)] 没有做你认为它做的事情

你快到了。这是您需要的正则表达式:

(?<id>\d+),(?<name>\w+),(?<active>[01]),(?<predecessor>\d+|null)

the regex demo 中,查看右侧窗格中的组捕获

说明

  • 主要区别是最后一组:(?&lt;predecessor&gt;\d+|null)
  • [\d+|(null)] 所拥有的是一个字符类,它匹配一个字符,该字符要么是数字,要么是其中之一:|(n、@987654328 @、l)

  • 相比之下,\d+|null 匹配数字或字符串 null,这是您的意图

要遍历组,您可以执行以下操作:

Pattern regex = Pattern.compile("(?<id>\\d+),(?<name>\\w+),(?<active>[01]),(?<predecessor>\\d+|null)");
Matcher regexMatcher = regex.matcher(yourString);
while (regexMatcher.find()) {
        // do something with regexMatcher.group("id")
        // do something with regexMatcher.group("name")
        // do something with regexMatcher.group("active")
        // do something with regexMatcher.group("predecessor")
} 

【讨论】:

  • 像魅力一样工作。非常感谢你的解释。你真的帮助我理解了如何使用正则表达式以及如何迭代多个匹配项:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多