Шаблон регулярных выражений справки Java / Groovy - PullRequest
2 голосов
/ 17 ноября 2010

Я пытаюсь разобрать что-то вроде этого: Key1=[val123, val456], Key2=[val78, val123]

в Map<String, List<String>> Вероятность состоит в том, что и ключ, и значения могут иметь не-буквенные символы, такие как .:-_

Это похоже на то, что я должен быть в состоянии использовать сопоставление / групповое сопоставление с регулярным выражением для выполнения короткой работы без разбора, но мне не повезло, что выражение регулярного выражения работает.Гуру регулярных выражений?

Ответы [ 4 ]

6 голосов
/ 17 ноября 2010

Попробуйте

([^=\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 голосов
/ 17 ноября 2010

Вот способ в 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 голосов
/ 02 декабря 2010

Более идиоматический способ построения по методу Барта:

def map = [:]
("Key1=[val123, val456], Key2=[val78, val123, val666]" =~ /(\S+)=\[([^]]*)]/ ).each { text, key, value ->
    map[key] = value.split(/,\s*/)
}
0 голосов
/ 17 ноября 2010

Вы можете заставить свой пример работать, используя этот 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

Однако (конечно) это не всегда возможно

...