如何像字符串一样拆分命令行



基本上,我需要像这样拆分字符串

"one quoted argument" those are separate arguments "but not "this one""

获取结果参数列表

  • "一个引用的论点"
  • 那些
  • 分开
  • "
  • 但不是"这个"

这个正则表达式"("|[^"])*"|[^ ]+几乎可以完成这项工作,但问题是正则表达式总是(至少在 java 中)试图匹配尽可能长的字符串。

因此,当我将正则表达式应用于以带引号的参数开头和结尾的字符串时,它会匹配整个字符串,并且不会为每个参数创建一个组。

有没有办法调整这个正则表达式或匹配器或模式或任何来处理它的东西?

注意:不要告诉我我可以使用GetOptCommandLine.parse或其他类似的东西。
我担心的是纯 java 正则表达式(如果可能的话,但我对此表示怀疑......

您可以使用

非贪婪限定符*?使其工作:

"(\"|[^"])*?"|[^ ]+

有关实际操作的示例,请参阅此链接:http://gskinner.com/RegExr/?32srs

正则表达式总是(至少在 Java 中)尝试匹配 最长的字符串可能。

嗯......不。

这是由你是否使用贪婪或非贪婪的表达来控制的。请参阅一些示例。使用非贪婪的(通过添加问号)应该可以做到。这称为延迟量化。

默认是贪婪的,但这并不意味着它总是这样。

public static String[] parseCommand( String cmd )
{
    if( cmd == null || cmd.length() == 0 )
    {
        return new String[]
        {};
    }
    cmd = cmd.trim();
    String regExp = ""(\"|[^"])*?"|[^ ]+";
    Pattern pattern = Pattern.compile( regExp, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE );
    Matcher matcher = pattern.matcher( cmd );
    List< String > matches = new ArrayList< String >();
    while( matcher.find() ) {
        matches.add( matcher.group() );
    }
    String[] parsedCommand = matches.toArray(new String[] {});
    return parsedCommand;
}

我想出了这个(感谢Alex给了我很好的起点:))

/**
 * Pattern that is capable of dealing with complex command line quoting and
 * escaping. This can recognize correctly:
 * <ul>
 * <li>"double quoted strings"
 * <li>'single quoted strings'
 * <li>"escaped "quotes within" quoted string"
 * <li>C:pathslikethis or "C:path likethis"
 * <li>--arguments=like_this or "--args=like this" or '--args=like this' or
 * --args="like this" or --args='like this'
 * <li>quoted whitespaces\t (spaces & tabs)
 * <li>and probably more :)
 * </ul>
 */
private static final Pattern cliCracker = Pattern
    .compile(
       "[^\s]*"(\\+"|[^"])*?"|[^\s]*'(\\+'|[^'])*?'|(\\\s|[^\s])+",
       Pattern.MULTILINE);

最新更新