对于解析播放器命令,我经常使用split方法通过分隔符拆分字符串,然后通过一系列if
s或{{1来计算其余部分}}上课。在Java中解析字符串有哪些不同的方法?
答案 0 :(得分:19)
我真的很喜欢正则表达式。只要命令字符串相当简单,您就可以编写一些可能需要几页代码来手动解析的正则表达式。
我建议您查看http://www.regular-expressions.info以获取正则表达式的详细介绍,以及Java的具体示例。
答案 1 :(得分:15)
我假设您正在努力使命令界面尽可能宽容。如果是这种情况,我建议您使用类似于此的算法:
答案 2 :(得分:13)
手动解析很有趣......开头:)
实际上,如果命令不是很复杂,您可以像命令行解释器中使用的那样处理它们。您可以使用以下库列表:http://java-source.net/open-source/command-line。我认为您可以从apache commons CLI或args4j开始(使用注释)。它们有很好的文档记录,使用起来非常简单。它们自动处理解析,您唯一需要做的就是读取对象中的特定字段。
如果你有更复杂的命令,那么创建一个正式的语法可能是一个更好的主意。有一个非常好的库,带有用于语法的图形编辑器,调试器和解释器。它被称为ANTLR(和编辑器ANTLRWorks)并且它是免费的:)还有一些示例语法和教程。
答案 3 :(得分:7)
我会查看Java migrations的Zork,并倾向于简单Natural Language Processor(通过令牌化或正则表达式驱动),例如以下内容(来自此链接):
public static boolean simpleNLP( String inputline, String keywords[]) { int i; int maxToken = keywords.length; int to,from; if( inputline.length() = inputline.length()) return false; // check for blank and empty lines while( to >=0 ) { to = inputline.indexOf(' ',from); if( to > 0){ lexed.addElement(inputline.substring(from,to)); from = to; while( inputline.charAt(from) == ' ' && from = keywords.length) { status = true; break;} } } return status; }
...
任何让程序员再次看到Zork的理由在我的书中都很好,只需要留意Grues。
...
答案 4 :(得分:6)
Sun本身建议远离StringTokenizer并改为使用String.spilt方法。
您还需要查看Pattern类。
答案 5 :(得分:6)
对ANTLR / ANTLRWorks的另一次投票。如果你创建了两个版本的文件,一个是用于实际执行命令的Java代码,另一个是没有(只有语法),那么你就拥有了该语言的可执行规范,非常适合测试,对于文档来说是一个福音如果您决定移植它,那么节省大量时间。
答案 6 :(得分:4)
如果要解析命令行,我建议使用Commons Cli。
Apache Commons CLI库提供了一个用于处理命令行界面的API。
答案 7 :(得分:4)
尝试JavaCC Java的解析器生成器。
它有很多用于解释语言的功能,并且在Eclipse上得到了很好的支持。
答案 8 :(得分:2)
@CodingTheWheel继承你的代码,有点清理并通过eclipse( ctrl + shift + f )并在此处插入: )
包括每行前面的四个空格。
public static boolean simpleNLP(String inputline, String keywords[]) {
if (inputline.length() < 1)
return false;
List<String> lexed = new ArrayList<String>();
for (String ele : inputline.split(" ")) {
lexed.add(ele);
}
boolean status = false;
to = 0;
for (i = 0; i < lexed.size(); i++) {
String s = (String) lexed.get(i);
if (s.equalsIgnoreCase(keywords[to])) {
to++;
if (to >= keywords.length) {
status = true;
break;
}
}
}
return status;
}
答案 9 :(得分:1)
空格上的简单字符串标记符应该可以工作,但是有很多方法可以做到这一点。
以下是使用标记生成器的示例:
String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;
if (tokens.hasMoreTokens()) {
action = tokens.nextToken();
}
if (action != null) {
doCommand(action, tokens);
}
然后令牌可以进一步用于参数。这一切都假设参数中没有使用空格...所以你可能想要推出自己的简单解析机制(比如获取第一个空格并在之前使用文本作为动作,或者如果你不介意那么使用正则表达式)速度命中),只是将其抽象出来,以便可以在任何地方使用。
答案 10 :(得分:1)
当命令的分隔符String总是相同的String或char(如“;”)y建议您使用StrinkTokenizer类时:
但是当分隔符变化或复杂时,建议您使用常规表达式,这可以由String类本身使用,方法分割,从1.4开始。它使用java.util.regex包中的Pattern类
答案 11 :(得分:1)
如果语言很简单,就像
一样VERB NOUN
然后用手拆分效果很好。
如果它更复杂,你应该真正研究像ANTLR或JavaCC这样的工具。
我在http://javadude.com/articles/antlrtut有一个关于ANTLR(v2)的教程,可以让你了解它是如何工作的。
答案 12 :(得分:1)
JCommander似乎相当不错,虽然我还没有测试过。
答案 13 :(得分:1)
如果您的文字包含一些分隔符,那么您可以使用split
方法
如果文本包含不规则字符串,则表示格式不同,则必须使用regular expressions
。
答案 14 :(得分:1)
split方法可以将字符串拆分为指定子字符串表达式regex
的数组。
它的参数有两种形式,即:split(String regex
)和split(String regex, int limit
),其中split(String regex
)实际上是通过调用split(String regex,int limit)来实现的, 限制为0 。然后,当限制&gt; 0 和限制&lt; 0 代表什么?
当 jdk 解释时: limit&gt; 0 子数组长度达到限制,即,如果可能,可以 limit-1 细分,保留为子字符串(除了字符数限制为字符串的1倍)分裂结束);
limit&lt; 0 表示对数组的长度没有限制;
limit = 0 字符串空字符串的结尾将被截断。
StringTokenizer
类是出于兼容性原因而保留的遗留类,因此我们应该尝试使用String类的split方法。
参考link