在Java中parsingstring有哪些不同的方法?

为了parsing玩家命令,我经常使用split方法通过分隔符来分割一个string,然后通过一系列的if或者switch来找出其余的。 在Java中parsingstring有什么不同的方法?

我假设你试图使命令界面尽可能宽容。 如果是这样的话,我build议你使用类似这样的algorithm:

  1. 阅读string
    • 将string拆分为令牌
    • 使用字典将同义词转换为常见的forms
    • 例如,将“打”,“打”,“打”和“踢”转换为“打”
    • 在无序的包容性基础上执行操作
    • 无序 – “在脸上打猴子”和“猴子脸上的脸”是一回事,
    • 包容性 – 如果命令是“殴打猴子的脸”,他们提供“打孔猴子”,你应该检查这匹配的命令。 如果只有一个命令,请执行此操作。 拥有指挥优先权甚至可能是一个好主意,即使有匹配,也会执行最高行动。

我真的很喜欢正则expression式。 只要命令string相当简单,您可以编写几个正则expression式,这些正则expression式可能需要几页代码才能手动parsing。

我build议你查看http://www.regular-expressions.info ,了解正则expression式,以及Java的具体示例。

手动parsing是很有趣的…在开始:)

在实践中,如果命令不是非常复杂的话,你可以像命令行解释器中那样对待它们。 有一个你可以使用的库列表: http : //java-source.net/open-source/command-line 。 我想你可以从apache commons CLI或args4j开始 (使用注释)。 他们是有据可查的,使用起来非常简单。 他们自动处理parsing,唯一需要做的就是读取对象中的特定字段。

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

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

你也想看看Pattern类。

我会看看Zork的 Java迁移 ,并倾向于一个简单的自然语言处理器 (通过标记化或正则expression式驱动),比如下面的(从这个链接):

     public static boolean simpleNLP(String inputline,String keywords [])
     {
         int i;
         int maxToken = keywords.length;
        从...到
         if(inputline.length()= inputline.length())返回false;  //检查空白和空行
         while(to> = 0)
         {
             to = inputline.indexOf('',from);
            如果(> 0){
                 lexed.addElement(inputline.substring(从,到));
                从=到;
                 while(inputline.charAt(from)==''
                 && from = keywords.length){status = true; 打破;}
             }
         }
        退货状态;
     }

任何让程序员再次看Zork的理由在我的书里都是好的,只要注意Grues。

另一个投票ANTLR / ANTLRWorks。 如果您创build了两个版本的文件,一个是用于实际执行命令的Java代码,另一个是没有(只有语法)的文件,那么您有一个可执行的语言规范,这对testing非常有用, ,如果你决定移植它,那么这是一个很大的时间。

如果这是parsing命令行,我会build议使用Commons Cli 。

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

尝试JavaCC Java的parsing器生成器。

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

@CodingTheWheelinheritance你的代码,有点清理并通过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; } 

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

这是一个使用标记器的例子:

 String command = "kick person"; StringTokenizer tokens = new StringTokenizer(command); String action = null; if (tokens.hasMoreTokens()) { action = tokens.nextToken(); } if (action != null) { doCommand(action, tokens); } 

然后令牌可以进一步用于参数。 这一切都假设参数中没有空格…所以你可能想要推出你自己的简单的parsing机制(如获取第一个空白,并使用前面的文本作为行动,或使用正则expression式,如果你不介意速度打击),只是抽象出来,所以它可以在任何地方使用。

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

StringTokenizer的

但是当分隔符变化或复杂时,build议您使用正则expression式,至less1.4可以被String类自身使用。 它使用java.util.regex包中的Pattern类

模式

如果这种语言像刚刚那样简单

动词名词

然后用手分开效果很好。

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

我在http://javadude.com/articles/antlrtut上有一个关于ANTLR(v2)的教程,它会告诉你它是如何工作的。;

JCommander似乎相当不错,虽然我还没有testing它。

如果你的文本包含一些分隔符,那么你可以使用你的split方法。
如果文本包含不规则string,则表示格式不同,则必须使用regular expressions

split方法可以将一个string拆分成指定的子stringexpression式regex的数组。 它的参数有两种forms,即:split( String regex )和split( String regex, int limit ),其中split( String regex )实际上是通过调用split(String regex,int limit)来实现的, limit是0 。 那么,当极限> 0极限<0代表什么?

jdk解释:当limit> 0时,子数组长度达到限制,也就是说,如果可能的话,可以将limit-1细分,剩下作为子string(除了limit-1时, ;

限制<0表示对arrays的长度没有限制;

limit = 0string结尾的空string将被截断。 StringTokenizer类是出于兼容性的原因,并保留旧类,所以我们应该尝试使用String类的split方法。 请参阅链接