正则表达式查找成对的字符串

| 我在http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/中找到了这个很棒的gant脚本/感谢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*[\"\'](.*?)[\"\']/
并将其填充到属性中。但是由于正则表达式无法找到成对的“代码和默认”部分,因此无法使用。 任何想法如何更改正则表达式或整个脚本来做到这一点?
已邀请:
您的正则表达式不正确。对于以下消息方法调用:
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\']
除了像彩旗一样提供更好的正则表达式外,我还找到了一个非常有用的Grails插件:message-reports
更好的正则表达式来解决它是:
/code=[\"\'](.*?)[\"\'].*default=\\s*[\"\'](.*?)[\"\']/
输出格式可以是
properties << it[1]+\"=\"+it[2]
结果
product.label=Product
我对此脚本做了一些工作,发现了一些需要注意的细节。我想查找具有和未定义默认值的邮件,也想查找非标签版本(即
${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}\")
}
这样,我无法在一行中混合使用默认值和没有默认值的消息。我现在可以忍受。 玩得开心!

要回复问题请先登录注册