所以我知道这个问题以前可能被问过很多次,但当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]