如何使用优先级正则表达式/模式匹配来划分一行,Java

时间:2015-04-20 18:07:05

标签: java regex

所以我知道这个问题之前可能已经被问了很多次,但是当我在命令行上查看运行参数时,我实际上是在尝试做与JVM相同的事情,例如:

java MyProgram arg1 arg2 "argument three" arg4

优先级匹配是如果参数是引号,将其视为一个参数;否则,用空格分隔。

我正在阅读CSV文件,但有时会在引号中包含一个部分,因此它可能如下所示:

value, value, value, value, "value, value", value

因此,它从String.split().

向返回的数组添加了一个元素

正在使用的正则表达式:

String[] data = line.split("(\".*\")|,", -1);

基本上我试图说,如果有双引号后跟任何内容,接着是另一个引用,则将其视为优先级(左 - 右);否则,根据逗号分割它。

这个正则表达式似乎并没有起作用,因为我仍然在该行上获得的值多于文件中的字段(标题)。

任何帮助都会受到赞赏,我对正则表达式不是最好的。感谢。

2 个答案:

答案 0 :(得分:3)

您可以执行以下操作(使用分隔符匹配字符串作为空格和逗号,并忽略引号内的分隔符。相同问题的不同方法):

List<String> matchList = new ArrayList<String>();
Pattern regex = Pattern.compile("[^\\s,\\\"']+|\\\"([^\\\"]*)\\\"|'([^']*)'");
Matcher regexMatcher = regex.matcher(line);
while (regexMatcher.find()) {
    matchList.add(regexMatcher.group());
}

修改:您可以使用[^\\s,\\\"]+|\\\"([^\\\"]*)\\\"仅允许双引号(如uraimo所示)。

<强>输出:

[value, value, value, value, "value, value", value]

答案 1 :(得分:3)

您正在寻找:

  • 字符串的开头或逗号(?:^|,)后跟零或多个空格\s*,后跟引用",然后是任意数量的非引号字符{{1}然后是另一个引用([^"]*)然后是零或更多的空格"以及一个尾随逗号或行尾\s* - 它们在合并时会给(?=,|$)或< / LI>
  • 字符串的开头或逗号(?:^|,)\s*"([^"]*)"\s*(?=,|$)后跟零或多个非逗号字符(?:^|,)以及尾随逗号或行尾([^,]*)合并时(?=,|$)

将两者放在一起就可以得到正则表达式:

(?:^|,)([^,]*)(?=,|$)

你可以像这样实现它:

(?:^|,)(?:\s*"([^"]*)"\s*|([^,]*))(?=,|$)

如果您想将其扩展为允许在带引号的字符串中使用转义引号,那么您需要:

String test = "value, value, value, value, \"value, value\", value";

Pattern pattern = Pattern.compile( "(?:^|,)(?:\\s*\"([^\"]*)\"\\s*|([^,]*))(?=,|$)" );
Matcher matcher = pattern.matcher( test );
while( matcher.find() ){
    String value = matcher.group(1);
    if ( value == null )
        value = matcher.group(2).trim();
    System.out.println( value );
}

可以用Java编写,如下:

(?:^|,)(?:\s*"((?:[^"]|\\")*)"\s*|([^,]*))(?=,|$)