使用 Groovy 和正则表达式如何转换:
String shopping = "SHOPPING LIST(TOMATOES, TEA, LENTIL SOUP: packets=2) for Saturday"
打印出来
Shopping for Saturday
TOMATOES
TEA
LENTIL SOUP (2 packets)
我不是正则表达式大师,所以我找不到一个正则表达式来进行转换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"
变量。然后它处理字符串以将其转换为所需的输出,替换出现并用逗号分割列表(相当于)。list
day
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')
}
如果第一个正则表达式不匹配,则不会打印任何内容。
我喜欢在find
这类情况下使用 String 方法,我认为它比=~
语法更清晰:
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")
}