在Java中解析字符串有哪些不同的方法?

为了解析玩家命令,我经常使用 split 方法以分隔符分割字符串,然后通过一系列 if开关代码> ES。在Java中解析字符串有哪些不同的方法?

0
额外 编辑
意见: 3
我试图编辑这个问题,将它从基于意见的方式变为现实,但是我担心答案已经太过分了。
额外 作者 agweber,

14 答案

一个简单的字符串标记在空间应该工作,但有很多方法可以做到这一点。

以下是使用标记器的示例:

String command = "kick person";
StringTokenizer tokens = new StringTokenizer(command);
String action = null;

if (tokens.hasMoreTokens()) {
    action = tokens.nextToken();
}

if (action != null) {
    doCommand(action, tokens);
}

然后令牌可以进一步用于参数。这一切都假设参数中没有空格......所以你可能想要推出你自己的简单解析机制(比如获取第一个空格并使用之前的文本作为动作,或者如果你不介意使用正则表达式速度打击),只需将其抽象出来,以便随时随地使用。

0
额外
据我记得'StringTokenizer'已被删除,强烈建议不要由JDK文档使用它。
额外 作者 Ali Motevallian,

我假设你试图让命令界面尽可能宽容。如果是这种情况,我建议你使用类似这样的算法:

  1. Read in the string
    • Split the string into tokens
    • Use a dictionary to convert synonyms to a common form
    • For example, convert "hit", "punch", "strike", and "kick" all to "hit"
    • Perform actions on an unordered, inclusive base
    • Unordered - "punch the monkey in the face" is the same thing as "the face in the monkey punch"
    • Inclusive - If the command is supposed to be "punch the monkey in the face" and they supply "punch monkey", you should check how many commands this matches. If only one command, do this action. It might even be a good idea to have command priorities, and even if there were even matches, it would perform the top action.
0
额外

我真的很喜欢正则表达式。只要命令字符串非常简单,您可以编写几个正则表达式,这些正则表达式可能需要几页代码才能手动解析。

我建议你查看 http://www.regular-expressions.info ,以获得正确的介绍,以及Java的具体示例。

0
额外
如果给出一些示例代码来帮助新手,我很乐意接受这个答案。
额外 作者 agweber,
@Gaurav Vashishta,正则表达式可以用于 lexing ,但这只是解析的第一步。
额外 作者 Mike Samuel,

@CodingTheWheel继承自你的代码,通过eclipse( ctrl + shift + f )清理并插入到这里:)

包括每行前面的四个空格。

public static boolean simpleNLP(String inputline, String keywords[]) {
    if (inputline.length() < 1)
        return false;

    List lexed = new ArrayList(); 
    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;
}
0
额外

当命令的分隔符字符串全是相同的字符串或字符(如“;”)时,建议您使用StrinkTokenizer类:

StringTokenizer

但是当分隔符变化或复杂时,建议您使用常规表达式,自1.4开始,String类本身可以使用方法split。它使用java.util.regex包中的Pattern类

模式

0
额外

Sun本身建议远离StringTokenizer并使用String.spilt方法。

你也会想看看Pattern类。

0
额外

如果您的文本包含一些分隔符,那么您可以使用 split 方法 如果文本包含不规则的字符串,则表示格式不同,那么您必须使用正则表达式

0
额外

如果这种语言像正义一样简单

动词名词

然后用手分开效果很好。

如果它更复杂,你应该看看像ANTLR或JavaCC这样的工具。

我在 http://javadude.com/articles/antlrtut这会让你知道它是如何工作的。

0
额外

对ANTLR / ANTLRWorks进行另一次投票。如果您创建了两个版本的文件,一个是用于实际执行命令的Java代码,另一个是没有(仅使用语法)的文件,那么您可以执行该语言的可执行规范,这对于测试非常有用,是文档的福音,并且如果你决定移植它,那么这是一个很大的倍频程序。

0
额外

尝试 JavaCC Java解析器生成器。

它具有很多用于解释语言的功能,并且在Eclipse上得到了很好的支持。

0
额外

手动解析非常有趣...在开始:)

在实践中,如果命令不是很复杂,你可以像命令行解释器中那样对待它们。您可以使用一系列库: http://java-source.net/open -source /命令行。我认为您可以从 apache commons CLIargs4j (使用注释)。他们有很好的文件记录,使用起来非常简单。他们自动处理解析,并且唯一需要做的是读取对象中的特定字段。

如果你有更复杂的命令,那么创建一个正式的语法将是一个更好的主意。有一个非常好的图书馆,图形编辑器,调试器和语法解释器。它被称为 ANTLR (和编辑 ANTLRWorks ),它是免费的:)也有一些例子语法和教程。

0
额外

如果这是解析命令行,我建议使用 Commons Cli

Apache Commons CLI库提供了一个用于处理命令行界面的API。
0
额外

JCommander seems quite good, although I have yet to test it.

0
额外

split method can split a string into an array of the specified substring expression regex. Its arguments in two forms, namely: split (String regex) and split (String regex, int limit), which split (String regex) is actually by calling split (String regex, int limit) to achieve, limit is 0. Then, when the limit> 0 and limit <0 represents what?

When the jdk explained: when limit> 0 sub-array lengths up to limit, that is, if possible, can be limit-1 sub-division, remaining as a substring (except by limit-1 times the character has string split end);

limit <0 indicates no limit on the length of the array;

limit = 0 end of the string empty string will be truncated. StringTokenizer class is for compatibility reasons and is preserved legacy class, so we should try to use the split method of the String class. refer to link

0
额外