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



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

java MyProgram arg1 arg2 "argument three" arg4

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

我正在阅读一个CSV文件,但有时其中一部分包含在引号中,所以它可能看起来像这样:

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

因此,它在String.split().返回的数组中又添加了一个元素

我尝试使用的正则表达式:

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

所以本质上,我想说,如果有一个双引号后面跟着任何东西,后面跟着另一个引号,那么就把它当作优先级(左-右);否则,请根据逗号进行拆分。

不过,这个正则表达式似乎不起作用,因为我在这一行上仍然比文件中的字段(头)多得到一个值。

任何帮助都将不胜感激,我不是regex最好的。谢谢

您正在寻找其中之一:

  • 字符串的开头或逗号(?:^|,),后跟零个或多个空格s*,后跟引号",然后是任意数量的非引号字符([^"]*),然后是另一个引号",然后是零个或更多空格s*,再加上一个尾随逗号或行的末尾(?=,|$),组合后得到(?:^|,)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 );
}

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

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

它可以用Java写成:

Pattern pattern = Pattern.compile( "(?:^|,)(?:\s*"((?:[^"]|\\")*)"\s*|([^,]*))(?=,|$)" );

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

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]

最新更新