我如何为Groovy textwrap.dedent()

时间:2015-08-22 09:56:50

标签: groovy

Python和Groovy都有一个简洁的功能,允许你编写多行字符串:

def foo = '''\
    [owner]
    name=bar

    [database]
    server=127.0.0.1'''

与:

相同
def foo = '        [owner]\n        name=bar\n\n        [database]\n        server=127.0.0.1'

在Python中,textwrap.dedent()函数从文本的每一行中删除任何常见的前导空格。

是否有类似Groovy的Python textwrap.dedent()可以给我:

    def foo = '[owner]\nname=bar\n\n[database]\nserver=127.0.0.1'

2 个答案:

答案 0 :(得分:1)

尝试stripIndent

即:

foo.stripIndent()

答案 1 :(得分:0)

我最终根据this GO implementation编写了自己的实现。

/**
 * Dedent removes any common leading whitespace from every line in text.
 *
 * This can be used to make multiline strings to line up with the left edge of
 * the display, while still presenting them in the source code in indented
 * form.
 */
def dedent(text) {
    def whitespace_only = ~/(?m)^[ \t]+$/
    def leading_whitespace = ~/(?m)(^[ \t]*)(?:[^ \t\n])/

    text = text.replaceAll(whitespace_only, '')
    def indents = text.findAll(leading_whitespace) { match, $1 -> $1 }

    // Look for the longest leading string of spaces and tabs common to
    // all lines.
    def margin = null
    for (i = 0; i < indents.size(); i++) {
        if (i == 0) {
            margin = indents[1]
        } else if (indents[1].startsWith(margin)) {
            // Current line more deeply indented than previous winner:
            // no change (previous winner is still on top).
            continue
        } else if (margin.startsWith(indents[1])) {
            // Current line consistent with and no deeper than previous winner:
            // it's the new winner.
            margin = indents[1]
        } else {
            // Current line and previous winner have no common whitespace:
            // there is no margin.
            margin = ""
            break
        }
    }

    if (margin != "") {
        text = text.replaceAll(~"(?m)^${margin}", '')
    }
    return text
}

但我是Groovy的新生儿,虽然我的第一次测试代码看起来是正确的,但可能写得不好。