正则表达式查找字符串对

发布于 2024-11-02 17:00:59 字数 1241 浏览 0 评论 0 原文

我在 http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/谢谢斯特凡!

描述:创建 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")

我尝试通过以下方式扩展它。假设我们有一些消息属性,例如:

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

我们想要作为脚本的输出,例如:

product.label=Product

我尝试向正则表达式添加一些条件:

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

并将其填充到属性中。但由于正则表达式找不到成对的“代码和默认”部分,因此这是行不通的。

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

I have found this great gant script on http://blog.armbruster-it.de/2010/07/getting-a-list-of-all-i18n-properties-used-in-a-grails-application/ Thanks Stefan!

Description: create a list of all i18n properties used in groovy code and gsp templates

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")

I tried to extend it in the following way. Let's say we have soem message properties like:

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

What we want to have as output of the script something like:

product.label=Product

I tried to add some condition to the regex:

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

and to fill it to properties. But as the regex does not find pairs of "code and default"-parts this is not going to work.

Any idea how to change the regex or the whole script to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鸩远一方 2024-11-09 17:00:59

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

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']

Your regular expression is incorrect. For the following message method call:

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

It should look like this:

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']
夏雨凉 2024-11-09 17:00:59

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

Aside from providing a better regex as bunting did, I found a pretty useful Grails plugin: message-reports

枫以 2024-11-09 17:00:59

解决这个问题的更好的正则表达式是:

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

输出格式可以是

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

结果

product.label=Product

the better regex to solve it is:

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

output format can be

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

results

product.label=Product
沉鱼一梦 2024-11-09 17:00:59

我对这个脚本进行了一些研究,发现了一些需要注意的细节。我想查找带有和没有定义默认值的消息,并且我想找到非标记版本(即 ${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}")
}

不能在一行中混合带有默认值的消息了。

这样我就

I worked a bit with this script and found some details that needed attention. I want to find messages with and without defined defaults and I want to find the non-tag verson (i.e. ${g.message(code:"the.code", default:"the.default"}) as well.

It seems good to not go over the file's content but parse it line by line. This is because iIf there is a code in a line, I'll (in a second step) take a look if it has a default. Don't want to parse the whole file twice though.

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}")
}

Like this I cannot mix messages with and without default in a single line. I can live with that for now.

Have fun!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文