正则表达式找到字符串对

时间:2011-04-19 13:13:25

标签: regex grails gant

我在http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/感谢Stefan发现了这个伟大的脚本!

描述:创建groovy代码和gsp模板中使用的所有i18n属性的列表

def properties = []

new File(".").eachFileRecurse {
    if (it.file) {
        switch (it) {
            case ~/.*\.groovy/:
                def matcher = it.text =~ /code:\s*["'](.*?)["']/
                matcher.each { properties << it[1] }
                break
            case ~/.*\.gsp/:
                def matcher = it.text =~ /code=["'](.*?)["']/
                matcher.each { properties << it[1] }
                break
        }
    }
}
println properties.sort().unique().join("\n")

我尝试以下列方式扩展它。假设我们有soem消息属性,如:

message(code: 'product.label', default: 'Product')

我们希望将脚本输出为:

product.label=Product

我试图在正则表达式中添加一些条件:

def matcher = it.text =~ /code=["'](.*?)["'] | default=\s*["'](.*?)["']/

并将其填充到属性中。但由于正则表达式没有找到“代码和默认”对的部分,因此这不起作用。

知道如何更改正则表达式或整个脚本来执行此操作吗?

4 个答案:

答案 0 :(得分:2)

您的正则表达式不正确。对于以下消息方法调用:

message(code: 'product.label', default: 'Product')

它应该是这样的:

def properties = [:]
def txt = "message(code: 'product.label', default: 'Product')"
def matcher = txt =~ /code:\s*["'](.*?)["'].*default:\s*["'](.*?)["']/
matcher.each{ properties[it[1]] = it[2] }
assert properties == ['product.label':'Product']

答案 1 :(得分:1)

除了提供更好的正则表达式之外,我发现了一个非常有用的Grails插件:message-reports

答案 2 :(得分:0)

解决它的更好的正则表达式是:

/code=["'](.*?)["'].*default=\s*["'](.*?)["']/

输出格式可以是

properties << it[1]+"="+it[2]

结果

product.label=Product

答案 3 :(得分:0)

我使用这个脚本做了一些工作,发现了一些需要注意的细节。我想找到有和没有定义默认值的消息,我想找到非标签verson(即${g.message(code:"the.code", default:"the.default"})。

最好不要浏览文件的内容,而是逐行解析。这是因为如果行中有代码,我会(在第二步中)查看它是否有默认值。不想两次解析整个文件。

def properties = [:]

new File(".").eachFileRecurse { file ->
    if (file.file) {
        switch (file) {
            case ~/.*\.groovy/:
                file.eachLine {line ->
                    // check if there is a message in the current line
                    def matcherNoDefault = line =~ /code:\s*["'](.*?)["']/
                    // if there is one, check if it has a default
                    if (matcherNoDefault.getCount() > 0) {
                        def matcher = line =~ /code:\s*["'](.*?)["'].*default:\s*["'](.*?)["']/
                        if (matcher.getCount() > 0) {
                            matcher.each{ properties[it[1]] = it[2] }
                        } else {
                            matcherNoDefault.each{ properties[it[1]] = "NO_DEFAULT" }
                        }
                    }
                }
                break
            case ~/.*\.gsp/:
                file.eachLine {line ->
                    // check if there is a message in the current line (as a g.message(...) function)
                    def matcherNoDefault = line =~ /code:\s*["'](.*?)["']/
                    // if there is one, check if it has a default
                    if (matcherNoDefault.getCount() > 0) {
                        def matcher = line =~ /code:\s*["'](.*?)["'].*default:\s*["'](.*?)["']/
                        if (matcher.getCount() > 0) {
                            matcher.each{ properties[it[1]] = it[2] }
                        } else {
                            matcherNoDefault.each{ properties[it[1]] = "NO_DEFAULT" }
                        }
                    }

                    // check if there is a message in the current line (in tag form)
                    matcherNoDefault = line =~ /code=["'](.*?)["']/
                    // if there is one, check if it has a default
                    if (matcherNoDefault.getCount() > 0) {
                        def matcher = line =~ /code=["'](.*?)["'].*default=["'](.*?)["']/
                        if (matcher.getCount() > 0) {
                            matcher.each{ properties[it[1]] = it[2] }
                        } else {
                            matcherNoDefault.each{ properties[it[1]] = "NO_DEFAULT" }
                        }
                    }
                }
        }
    }
}
println properties.each {k, v ->
    println("${k}=${v}")
}

像这样,我不能在一行中混合有和没有默认的消息。我现在可以忍受这个。

玩得开心!