Java 从Clojure中的字符串解析命令行参数
我所处的情况是,我需要解析字符串中的参数,就像在命令行上提供给Java/Clojure应用程序时解析参数一样 例如,我需要将Java 从Clojure中的字符串解析命令行参数,java,regex,command-line,clojure,Java,Regex,Command Line,Clojure,我所处的情况是,我需要解析字符串中的参数,就像在命令行上提供给Java/Clojure应用程序时解析参数一样 例如,我需要将“foo\”bar baz\“'fooy barish'foo”转换为(“foo”“bar baz”“fooy barish”“foo”) 我很好奇,是否有一种方法可以使用Java或Clojure使用的解析器来实现这一点。我并不反对使用正则表达式,但我在正则表达式方面很差劲,如果我试图为此编写一个正则表达式,我会很失败 有什么想法吗?我最后做了以下工作: (filter s
“foo\”bar baz\“'fooy barish'foo”
转换为(“foo”“bar baz”“fooy barish”“foo”)
我很好奇,是否有一种方法可以使用Java或Clojure使用的解析器来实现这一点。我并不反对使用正则表达式,但我在正则表达式方面很差劲,如果我试图为此编写一个正则表达式,我会很失败
有什么想法吗?我最后做了以下工作:
(filter seq
(flatten
(map #(%1 %2)
(cycle [#(s/split % #" ") identity])
(s/split (read-line) #"(?<!\\)(?:'|\")"))))
(过滤器顺序
(变平
(地图#(%1%2)
(循环[#(s/split%#“”)标识])
(s/split(read line)#“(?更新了一个新的、甚至更复杂的版本。这在官方看来是荒谬的;下一次迭代将使用一个合适的解析器(或c.c.monads和一点类似于Parsec的逻辑)。请参阅此答案上的修订历史,了解原始版本
这组错综复杂的函数似乎起到了作用(很抱歉,我对这一个还不太了解):
这也是:
(= (split-args "asdf asdf ' asdf \" asdf ' \" foo bar ' baz \" \" foo bar \\\" baz \"")
'("asdf" "asdf" " asdf \" asdf " " foo bar ' baz " " foo bar \" baz "))
希望这可以修剪常规参数,而不是那些被引号包围的参数,处理双引号和单引号,包括在未加引号的双引号内加引号的双引号(请注意,它目前以相同的方式处理未加引号的单引号内加引号的单引号,这显然与*nix shell方式…argh不同)等等。请注意,它基本上是一个特殊状态单子中的计算,只是以一种特别难看的方式编写的,并且迫切需要干涸。:-P这个问题困扰了我,所以我让它在ANTLR中工作。下面的语法应该让你知道如何做。它包括对反斜杠转义序列的基本支持
让ANTLR在Clojure中工作太多了,无法在这个文本框中写入。不过我写了一篇关于它的文章
grammar Cmd;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
DQ = '"';
SQ = '\'';
BS = '\\';
}
@lexer::members {
String strip(String s) {
return s.substring(1, s.length() - 1);
}
}
args: arg (sep! arg)* ;
arg : BAREARG
| DQARG
| SQARG
;
sep : WS+ ;
DQARG : DQ (BS . | ~(BS | DQ))+ DQ
{setText( strip(getText()) );};
SQARG : SQ (BS . | ~(BS | SQ))+ SQ
{setText( strip(getText()) );} ;
BAREARG: (BS . | ~(BS | WS | DQ | SQ))+ ;
WS : ( ' ' | '\t' | '\r' | '\n');
我知道这是一个非常古老的线程,但我遇到了同样的问题,并使用java interop调用:
(CommandLineUtils/translateCommandline命令行)
来自。我认为您的shell负责分割命令行参数,而不是Java。不管怎样,我仍在寻找一种合适的方法来实现这一点。我担心这会被,比如说,“asdf”打破asdf'
。此外,反斜杠本身可能会被转义…只是指出一些事情,以防您想要修复它们,如果我找到了另一种解决方案,我会将其作为一个答案发布。的确。我知道这不太正确,但我在那一点上采取了我能得到的任何措施。天哪。我很震惊,我必须将这件事放在我的代码中。这应该是一个错误比实际情况更容易。谢谢:你知道,你可能会考虑把它放进一个小书库或一些东西里。认真地说,这可能比我更有用。这不应该是真的吗?<代码>(=(分裂的ARGS)FoBar BAZ”)(“Fo”“Bar”“BAZ”)错误< /代码>啊,对,将在一秒钟内修复。(可能也会让它变得有点枯燥。)好吧,这足够简单,可以修复——将str/split
表单包装为(mapcat#(str/split%#)(?)?
(= (split-args "asdf asdf ' asdf \" asdf ' \" foo bar ' baz \" \" foo bar \\\" baz \"")
'("asdf" "asdf" " asdf \" asdf " " foo bar ' baz " " foo bar \" baz "))
grammar Cmd;
options {
output=AST;
ASTLabelType=CommonTree;
}
tokens {
DQ = '"';
SQ = '\'';
BS = '\\';
}
@lexer::members {
String strip(String s) {
return s.substring(1, s.length() - 1);
}
}
args: arg (sep! arg)* ;
arg : BAREARG
| DQARG
| SQARG
;
sep : WS+ ;
DQARG : DQ (BS . | ~(BS | DQ))+ DQ
{setText( strip(getText()) );};
SQARG : SQ (BS . | ~(BS | SQ))+ SQ
{setText( strip(getText()) );} ;
BAREARG: (BS . | ~(BS | WS | DQ | SQ))+ ;
WS : ( ' ' | '\t' | '\r' | '\n');