应用带条件匹配的Groovy RegEx

时间:2012-06-30 14:05:39

标签: regex groovy

使用Groovy和正则表达式如何转换它:

String shopping = "SHOPPING LIST(TOMATOES, TEA, LENTIL SOUP: packets=2) for Saturday"

打印出来

Shopping for Saturday
TOMATOES
TEA
LENTIL SOUP (2 packets)

2 个答案:

答案 0 :(得分:3)

我不是一个正则表达式大师,所以我找不到一个正则表达式来进行replaceAll步骤中的转换(我认为应该可以这样做)。这虽然有效:

def shopping = "SHOPPING LIST(TOMATOES, TEA, LENTIL SOUP: packets=2) for Saturday"

def (list, day) = (shopping =~ /SHOPPING LIST\((.*)\) for (\w+)/)[0][1,2]
println "Shopping for $day\n" + 
        list.replaceAll(/: packets=(\d+)/, ' ($1 packets)')
            .replaceAll(', ', '\n')

首先,它将字符串"TOMATOES, TEA: packets=50, LENTIL SOUP: packets=2""Saturday"分别捕获到变量listday中。然后它处理list字符串以将其转换为所需的输出,替换"packets="次出现并用逗号分隔列表(.replaceAll(', ', '\n')等同于.split(', ').join('\n'))。

需要注意的一点是,如果shopping字符串与第一个正则表达式不匹配,则会尝试访问第一个匹配项([0])时抛出异常。你可以通过这样做来避免这种情况:

(shopping =~ /SHOPPING LIST\((.*)\) for (\w+)/).each { match, list, day ->
    println "Shopping for $day\n" + 
            list.replaceAll(/: packets=(\d+)/, ' ($1 packets)')
                .replaceAll(', ', '\n')
}

如果第一个正则表达式不匹配,则不会打印任何内容。

答案 1 :(得分:1)

我喜欢在这些情况下使用String find方法,我认为它比=~语法更清晰:

String shopping = "SHOPPING LIST(TOMATOES, TEA, LENTIL SOUP: packets=2) for Saturday"

def expected = """Shopping for Saturday
TOMATOES
TEA
LENTIL SOUP (2 packets)"""


def regex = /SHOPPING LIST\((.*)\) for (.+)/

assert expected == shopping.find(regex) { full, items, day ->
    List<String> formattedItems = items.split(", ").collect { it.replaceAll(/: packets=(\d+)/, ' ($1 packets)') }
    "Shopping for $day\n" + formattedItems.join("\n")
}