为了解析玩家命令,我最常使用 分裂 方法通过分隔符分割字符串,然后通过一系列来计算出其余部分 ifswitches.Java 中解析字符串有哪些不同的方法?

有帮助吗?

解决方案

我假设您正在尝试使命令界面尽可能宽容。如果是这种情况,我建议您使用类似于以下的算法:

  1. 读入字符串
    • 将字符串拆分为标记
    • 使用字典将同义词转换为通用形式
    • 例如,将“hit”、“punch”、“strike”和“kick”全部转换为“hit”
    • 在无序、包容的基础上执行操作
    • 无序 - “打猴子的脸”与“打猴子的脸”是一样的
    • 包括的 - 如果命令应该是“打猴子的脸”并且他们提供“打猴子”,您应该检查有多少个命令匹配。如果只有一个命令,则执行此操作。拥有命令优先级甚至可能是一个好主意,即使有匹配项,它也会执行顶级操作。

其他提示

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

我建议你看看 http://www.regular-expressions.info 有关正则表达式的详细介绍以及 Java 的具体示例。

手动解析很有趣......一开始:)

在实践中,如果命令不是很复杂,您可以像命令行解释器中使用的那样对待它们。您可以使用以下库的列表: http://java-source.net/open-source/command-line. 。我认为你可以从 阿帕奇公共 CLI 或者 参数4j (使用注释)。它们有详细的文档记录并且使用起来非常简单。它们自动处理解析,您唯一需要做的就是读取对象中的特定字段。

如果您有更复杂的命令,那么创建正式语法也许是一个更好的主意。有一个非常好的库,带有图形编辑器、调试器和语法解释器。它被称为 ANTLR (和编辑 ANTLRWorks)并且它是免费的:)还有一些示例语法和教程。

我会看看 Java 迁移佐克, ,并倾向于简单的 自然语言处理器 (由标记化或正则表达式驱动)如下所示(来自此链接):

    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。

...

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

您还需要查看 Pattern 类。

另一次投票给 ANTLR/ANTLRWorks。如果您创建该文件的两个版本,一个包含用于实际执行命令的 Java 代码,另一个不包含(仅包含语法),那么您就拥有了该语言的可执行规范,这对于测试非常有用,对于文档来说是一个福音,如果您决定移植它,可以节省大量时间。

如果这是为了解析命令行我建议使用 公共客户端.

Apache Commons CLI 库提供了用于处理命令行界面的 API。

尝试 JavaCC Java 的解析器生成器。

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

@CodingTheWheel 这是你的代码,经过一些清理并通过 eclipse (控制键+转移+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;
}

一个简单的空格字符串标记器应该可以工作,但是实际上有很多方法可以做到这一点。

这是使用分词器的示例:

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

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

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

然后标记可以进一步用于参数。这一切都假设参数中没有使用空格......因此您可能想要推出自己的简单解析机制(例如获取第一个空格并使用之前的文本作为操作,或者如果您不介意速度影响则使用正则表达式),只需将其抽象出来以便可以使用任何地方。

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

字符串分词器

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

图案

如果语言非常简单,就像

动词名词

然后用手劈开效果很好。

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

我在 ANTLR (v2) 上有一个教程 http://javadude.com/articles/antlrtut 这会让您了解它是如何工作的。

指挥官 看起来相当不错,虽然我还没有测试过。

如果您的文本包含一些分隔符,那么您可以 split 方法。
如果文本包含不规则字符串意味着其中格式不同,那么您必须使用 regular expressions.

split方法可以将一个字符串分割成指定子串表达式的数组 regex。其论证有两种形式,即:分裂 (String regex) 并拆分 (String regex, int limit),它分裂了(String regex)实际上是通过调用split(String regex, int limit)来实现的, 限制为 0. 。然后,当 限制> 0限制<0 代表什么?

当。。。的时候 jdk 解释:什么时候 限制> 0 子数组长度达到限制,也就是说,如果可能的话,可以 限制-1 细分,保留为子字符串(除了 limit-1 次字符有字符串分裂结束);

限制<0 表示数组长度没有限制;

限制 = 0 字符串末尾的空字符串将被截断。StringTokenizer 类是出于兼容性原因而保留的遗留类,所以我们应该尽量使用String类的split方法。参考 关联

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top