正则表达式模式帮助java/groovy

问题描述 投票:0回答:4

我正在尝试解析这样的内容:

Key1=[val123, val456], Key2=[val78, val123]

变成

Map<String, List<String>>
一个问题是键和值都可以包含非字母数字字符,例如
.:-_

这看起来我应该能够使用正则表达式模式匹配/分组来完成简短的工作而不需要解析,但是我没有任何运气让正则表达式正常工作。有正则表达式专家吗?

java regex parsing groovy
4个回答
6
投票

尝试

([^=\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 ]

2
投票

这是 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


0
投票

您可以使用此 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

但是(当然)这并不总是可能的


0
投票

基于 Bart 方法的更惯用的方法:

def map = [:]
("Key1=[val123, val456], Key2=[val78, val123, val666]" =~ /(\S+)=\[([^]]*)]/ ).each { text, key, value ->
    map[key] = value.split(/,\s*/)
}
© www.soinside.com 2019 - 2024. All rights reserved.