我正在尝试解析这样的内容:
Key1=[val123, val456], Key2=[val78, val123]
变成
Map<String, List<String>>
一个问题是键和值都可以包含非字母数字字符,例如 .:-_
这看起来我应该能够使用正则表达式模式匹配/分组来完成简短的工作而不需要解析,但是我没有任何运气让正则表达式正常工作。有正则表达式专家吗?
尝试
([^=\s]+)\s*=\s*\[\s*([^\s,]+),\s*([^\s,]+)\s*\]
这将匹配一个键/值对并提取反向引用 1 中的键、反向引用 2 中的第一个值和反向引用 3 中的第二个值。
在 Java 中,这可能看起来像这样:
Pattern regex = Pattern.compile("([^=\\s]+)\\s*=\\s*\\[\\s*([^\\s,]+),\\s*([^\\s,]+)\\s*\\]");
Matcher regexMatcher = regex.matcher(subjectString);
while (regexMatcher.find()) {
key = regexMatcher.group(1);
val1 = regexMatcher.group(2);
val2 = regexMatcher.group(3);
}
说明:
([^=\s]+) # Match one or more characters except whitespace or =
\s*=\s* # Match =, optionally surrounded by whitespace
\[\s* # Match [ plus optional whitespace
([^\s,]+) # Match anything except spaces or commas
,\s* # Match a comma plus optional whitespace
([^\s,]+) # Match anything except spaces or commas
\s*\] # Match optional whitespace and ]
这是 Groovy 中的一种方法:
import java.util.regex.*
def map = [:]
def matcher = "Key1=[val123, val456], Key2=[val78, val123, val666]" =~ /(\S+)=\[([^]]*)]/
matcher.each {
map.put(it[1], it[2].split(/,\s*/))
}
println map
产生:
[Key1:[val123, val456], Key2:[val78, val123, val666]]
测试装置可以在这里找到:http://ideone.com/6oFsU
您可以使用此 Groovy 让您的示例正常工作:
def str = 'Key1=[val123, val456], Key2=[val78, val123]'
class Evaluator extends Binding {
def parse( s ) {
GroovyShell shell = new GroovyShell( this );
shell.evaluate( s )
}
Object getVariable( String name ) { name }
}
new Evaluator().parse "[$str]".tr( '=', ':' )
但是你说你可以有更复杂的例子吗?
最好、最安全的解决方案是让生成输出的程序使用正确的数据格式,例如 xml 或 json
但是(当然)这并不总是可能的
基于 Bart 方法的更惯用的方法:
def map = [:]
("Key1=[val123, val456], Key2=[val78, val123, val666]" =~ /(\S+)=\[([^]]*)]/ ).each { text, key, value ->
map[key] = value.split(/,\s*/)
}