【问题标题】:How to get arguments that either are or are not surrounded by quotes using regex如何使用正则表达式获取被引号包围或未被引号包围的参数
【发布时间】:2017-01-31 20:38:09
【问题描述】:

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

字符串可能类似于:"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;
}

但我想知道是否有更好的方法将这两种情况组合成一个正则表达式。我以为我可以简单地对它们进行 OR:"[\\s*\"([^\"]+)\"\\s*]|[\\s*([^\"\\s]+)\\s*]" 但这不起作用(在我的示例中,它与第一个 " 匹配,之后的一切都是错误的)

【问题讨论】:

  • 使用 "([^"]*)"|\S+ 并检查 Group 1 是否不为空。如果不是,则抓取group(1),否则,抓取group(0)
  • @WiktorStribiżew 谢谢!那行得通。

标签: java regex


【解决方案1】:

假设您在命令行参数中没有转义实体(没有转义引号),您可以使用单个正则表达式将带引号和不带引号的参数与 "([^"]*)"|\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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    • 2017-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-26
    相关资源
    最近更新 更多