Regex, чтобы найти пары строк - PullRequest
0 голосов
/ 19 апреля 2011

Я нашел этот замечательный сценарий Ганта в http://blog.armbruster -it.de / 2010/07 / получение списка всех свойств i18n, используемых в приложении grails / Спасибо, Стефан!

Описание: создать список всех свойств i18n, используемых в коде groovy и шаблонах gsp

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 ]

2 голосов
/ 19 апреля 2011

Ваше регулярное выражение неверно.Для следующего вызова метода сообщения:

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 голос
/ 20 апреля 2011

Помимо предоставления лучшего регулярного выражения, как это сделала овсянка, я нашел довольно полезный плагин Grails: message-reports

0 голосов
/ 11 марта 2013

Я немного поработал с этим сценарием и нашел некоторые детали, которые требуют внимания. Я хочу найти сообщения с определенными значениями по умолчанию и без них, а также найти не-тег версии (т. Е. ${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}")
}

Таким образом, я не могу смешивать сообщения с и без по умолчанию в одной строке. Я могу жить с этим сейчас.

Веселись!

0 голосов
/ 20 апреля 2011

лучшее решение для его решения:

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

формат вывода может быть

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

Результаты

product.label=Product
...