标记化输入的最佳方式

时间:2014-07-25 20:51:29

标签: java sql tokenize

我正在尝试使用以下内容将输入标记为程序:

create table users schema {firstName: string, lastName: string, age:number, address: string}
insert on users values {firstName: foo, lastName: bar, age:1, address: 32 foobar street}

我希望令牌出现如下:

Token 1: insert
Token 2: on
Token 3: users
Token 4: values
Token 5: {firstName: foo, lastName: bar, age:1, address: 32 foobar street}

这是我试图使用的类似SQL的语法。正则表达式是最好的方式还是还有别的东西?

2 个答案:

答案 0 :(得分:1)

我认为处理这个特定问题的最好方法是在循环中使用正则表达式。

Pattern pat = Pattern.compile("\\{.*?\\}|[^ \\{]+");
Matcher m = pat.matcher(source);
while (m.find()) {
    String token = m.group(0);
    // add to an ArrayList or whatever
}

该模式寻找:

  • 左大括号,后跟任何东西,然后是右大括号。 (必须在大括号之前插入反斜杠,否则它们具有特殊含义。.*?表示匹配零个或多个字符,?意味着尽可能少,以防多个}在输入中。

  • 任何不空白或{的字符序列。

循环将依次找到每个这样的标记; m.group(0)返回匹配的字符串。

使用一个正则表达式会使返回可变数量的标记变得困难。使用split通常是将字符串拆分为可变数量的标记的好方法,但这种情况有点太复杂,无法找出正确的分隔符。 (我确信它可行,但会让你的代码更难理解。)

我已经对您提供的两个输入样本进行了测试,我认为它可以提供您想要的结果。

答案 1 :(得分:0)

这个正则表达式

    ^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(\{.*\}).*$

适用于您的两个给定输入,但对于(未声明的)语法有效的输入几乎肯定会失败。

如果您愿意接受对输入语法的轻微更改,您可能需要考虑使用json(并使用java' s解析器,杰克逊:https://github.com/FasterXML/jackson