基本上,我需要将字符串拆分为
"one quoted argument" those are separate arguments "but not \"this one\""
获取参数列表
的结果这个正则表达式"(\"|[^"])*"|[^ ]+
几乎完成了这项工作,但问题是正则表达式总是(至少在java中)尝试匹配最长的字符串。
因此,当我将正则表达式应用于以带引号的参数开头和结尾的字符串时,它匹配整个字符串,并且不为每个参数创建一个组。
有没有办法调整这个正则表达式或matcher或pattern或其他什么来处理它?</ p>
注意:请勿告诉我,我可以使用GetOpt
或CommandLine.parse
或其他类似内容
我关注的是纯java正则表达式(如果可能的话,我怀疑它......)。
答案 0 :(得分:4)
嗯......不。正则表达式总是(至少在java中)尝试匹配 最长的字符串。
如果您使用贪婪或非贪婪的表达式,则由此控制。见some examples。使用非贪婪的(通过添加问号)应该这样做。它被称为lazy quantification。
默认是贪婪的,但这并不意味着它总是这样。
答案 1 :(得分:4)
答案 2 :(得分: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;
}
答案 3 :(得分:2)
我想出了这个(感谢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:\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);