1

我的 java 应用程序有一个小命令行。为了首先解析参数,该行被读入,然后使用string.split("\\s+"). 参数的形式为 name:value,通常namevalue都不应该有空格。

当值应该是文件路径时,我遇到了一个问题。如果路径包含空格(转义或不转义),则斩波算法当然只会拆分路径。

问:什么正则表达式允许我将字符串拆分为参数数组而不拆分(转义)文件路径。


我认为转义路径的形式是/folder/part1\ part2.txt,但合理的替代语法也是有效的。

如果更容易string.split(" ")也是可以接受的。

4

2 回答 2

1

最好的代码不是写出来的代码。所以,不要自己解析命令行。使用流行的库之一。例如旧的jackarta cli 项目或现代的、基于注释的库args4j

于 2013-05-10T13:32:06.237 回答
0

对于语法/folder/part1\ part2.txt::

解决这个问题的正则表达式需要一个否定的look-behind,以检查我们正在寻找的模式之前的字符是否不是\. 正则表达式是(?<!\\)\s+:(?<!\\)是后面的部分,\\是我们不想看到的模式。\s+是我们正在寻找的模式——某种空间。要在 java 中使用这个正则表达式,你必须正确地转义它,如:string.split("(?<!\\\\)\\s+").

这适用于 UNIX 样式的文件路径,如果要将文件传递new File()给例如,则可能必须删除反斜杠。


对于语法"/folder/part1 part2.txt"

这可能是一种更通用的方法,但会引入额外的工作。这个想法是循环字符串,每次我们看到一个空格时,我们都会将前一部分保存到一个列表中,除非空格在转义部分中。例如:

List<String> parts = new ArrayList<String>();
boolean escaped = false;
StringBuilder stringBuilder = new StringBuilder();
for(int i = 0; i < string.length(); i++) {
    char c = string.charAt(i);
    if(!escaped && (c == ' ' || c == '\t')) {    // Space in non-escaped part
        parts.add(stringBuilder.toString());     // Put buffer in list
        stringBuilder = new StringBuilder();
    } else if (c == '"')       // Escape sign
        escaped = !escaped;    // Toggle escape status
    else
        stringBuilder.append(c);    // Add char to buffer
}
parts.add(stringBuilder.toString());    // Put the last buffer into the array

如有必要,可以使用将列表转换为数组

String[] args = parts.toArray(new String[parts.size()])

这种格式允许 UNIX 和 Windows 样式的路径。结果数组将包含不带引号的文件路径。

于 2013-05-11T11:11:40.363 回答