如何使用正则表达式获取引号包围或不包含引号的参数

时间:2017-01-31 20:38:10

标签: java regex

我正试图找到从字符串中获取参数的最佳方法。

字符串可能如下所示:"exArg1" exArg2 "exArg3 with space" exArg4 exArg5

我希望将匹配项放在包含5个条目"exArg1" "exArg2" "exArg3 with space" "exArg4" "exArg5"

的字符串列表中

我的代码首先找到由字符串包围的参数,然后找到没有被字符串包围的参数,这是有效的

public static List<String> getArgs(String args){
    List<String> argList = new ArrayList<>();

    //Get all arguments surrounded by quotes
    String regex = "\\s*\"([^\"]+)\"\\s*";

    Pattern pattern = Pattern.compile(regex);
    Matcher match   = pattern.matcher(args);

    while (match.find())
    {
        if (match.groupCount() != 0)
        {
            if (match.group(1) != null)
            {
                argList.add(match.group(1));
                args = args.replaceAll(match.group(), " ");
                match = pattern.matcher(args);
            }
        }
    }

    //Get all arguments not surrounded by quotes
    regex = "\\s*([^\"\\s]+)\\s*";
    pattern = Pattern.compile(regex);
    match   = pattern.matcher(args);

    while (match.find())
    {
        if (match.groupCount() != 0)
        {
            if (match.group(1) != null)
            {
                argList.add(match.group(1));
            }
        }
    }

    return argList;
}

但我想知道是否有更好的方法将两个案例合并为一个正则表达式。我认为我可以简单地将它们作为原样:"[\\s*\"([^\"]+)\"\\s*]|[\\s*([^\"\\s]+)\\s*]"但是这不起作用(它匹配第一个&#34;在我的例子中,从那里后面的一切都是错误的)

1 个答案:

答案 0 :(得分:0)

假设您在命令行参数中没有转义实体(没有转义引号),您可以使用单个正则表达式将引用和不引用的参数与"([^"]*)"|\S+正则表达式匹配。检查第1组是否 null ,如果不是,请抓住group(1),否则,抓住group(0)

要支持转义双引号,请使用"([^"\\]*(?:\\.[^"\\]*)*)"|\S+正则表达式。

示例Java code

String str = "\"exArg1\" \"exArg2\" \"exArg3 with space\" exArg4 \"exArg5\"";
Pattern ptrn = Pattern.compile("\"([^\"]*)\"|\\S+"); 
// Or "\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"|\\S+" to support escaped quotes
Matcher matcher = ptrn.matcher(str);
List<String> result = new ArrayList<>();
while (matcher.find()) {
    if (matcher.group(1) == null) {
        result.add(matcher.group(0));
    } else {
        result.add(matcher.group(1));
    }
}
System.out.println(result); // => [exArg1, exArg2, exArg3 with space, exArg4, exArg5]