如何在groovy中验证Map片段

时间:2016-08-14 04:23:02

标签: groovy

我有一个生成groovy的动态html文件。这个html模板格式的一部分是{routeId}{groovyMap},如此

 USER_FORM[name:'Dean', user:randomFunction([item:'s', day:'Tuesday'])]

或类似

 USER_FORM[name: 'Dean', user: user]

我让第一个例子更复杂。目前,我拆分':'并验证提供的所有密钥。我想做的是拿着groovy片段并抓住所有键并验证

 1. all keys are strings
 2. validate the keys against some meta data I already have

我根本不关心价值观。目前,我分为':',但显然这不适用于所有情况。我担心其他可能没有考虑过的复杂案例。

这是一个模板引擎,如果可能的话,我更愿意尽快使用,以便在出现问题时让用户更容易。

3 个答案:

答案 0 :(得分:1)

如果我找对你,你可以使用类似的东西:

String val = "USER_FORM[name:'Dean', user:randomFunction([item:'s', day:'Tuesday'])]"
def res = []
val.eachMatch( /[\[,] ?(\w+):/ ){ res << it[ 1 ] }
assert '[name, user, item, day]' == res.toString()

答案 1 :(得分:1)

  
      
  1. 所有键都是字符串
  2.   

使用文字语法创建Map,即

Map m = [foo: 'bar']

而不是

Map m = new HashMap()
m.put('foo', 'bar')

键是始终字符串,即使您的作用域中的变量与键的名称相同。例如,在以下代码段中,键将是字符串'foo',而不是整数6

def foo = 6
Map m = [foo: 'bar']

使用带有 not 字符串的键的文字语法创建Map的唯一方法是,如果您的作用域中的变量与键的名称相同< em>和将密钥名称包装在括号中。例如,在以下代码段中,键将是整数6,而不是字符串'foo'

def foo = 6
Map m = [(foo): 'bar']
  

目前,我分开了&#39;:&#39;但显然不会为所有案件工作。我担心其他可能没有考虑过的复杂案例。

使用正则表达式/字符串拆分解析地图文字似乎是一个坏主意,因为您可能最终会严重重新实现Groovy词法分析器。像下面这样的东西似乎是一个更好的选择

def mapString = '[foo: "bar"]'    
Map map = Eval.me(mapString)

// now you can process the map via the Map interface, e.g.
map.keySet().toList() == ['foo']

答案 2 :(得分:1)

我同意其他人要避免直接解析。

如果您使用GroovyShell,则可以使用no-op methodMissingpropertyMissing处理程序来填充输入字符串。通过这种方式,即使是复杂的例子也可以。

请参阅下面的代码,包括测试用例(从&#34中提取地图字符串; USER_FORMstr&#34;格式留给读者)。

class KeyGenerator {
    // these could be "final static". omitted for brevity
    def shell = new GroovyShell() 
    def methodMissingHandler = "def methodMissing(String name, args) {}"
    def propertyMissingHandler = "def propertyMissing(String name) {}"

    def generateKeys(mapStr) {
        def evalInput = "${methodMissingHandler} ; " +
                        "${propertyMissingHandler} ; " + 
                        "${mapStr}"
        def map = shell.evaluate(evalInput)
        return map.keySet()
    }
}

// ------- main

def keyGenerator = new KeyGenerator()
def expected = new HashSet()
expected << "name"
expected << "user"

def mapStr = "[name:'Dean', user:randomFunction([item:'s', day:'Tuesday'])]"
assert expected == keyGenerator.generateKeys(mapStr)

def mapStr2 = "[name: 'Dean', user: user]"
assert expected == keyGenerator.generateKeys(mapStr2)
相关问题