3

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

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

得到参数列表

  • “一个引用的论点”
  • 那些
  • 分离
  • "但不是\"这个\""

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

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

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

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

4

4 回答 4

4

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

不。

如果您使用贪婪或非贪婪表达式,则可以控制它。看一些例子。使用非贪婪的(通过添加问号)应该做到这一点。这称为惰性量化

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

于 2012-11-21T14:37:28.330 回答
4

您可以使用非贪婪限定符*?使其工作:

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

请参阅此链接以获取实际示例: http://gskinner.com/RegExr/? 32srs

于 2012-11-21T14:40:29.947 回答
2
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;
}
于 2013-08-29T07:23:45.807 回答
2

我想出了这个(感谢亚历克斯给了我一个好的起点:))

/**
 * 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:\paths\like\this or "C:\path like\this"
 * <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);
于 2014-03-18T07:12:57.670 回答