2010-11-17 6 views
1

Je suis en train d'analyser quelque chose comme ceci: Key1=[val123, val456], Key2=[val78, val123]modèle regexp aide java/groovy

dans un Map<String, List<String>> Un prob est que la clé et les valeurs peuvent avoir des caractères non alpha num comme .:-_

Cela ressemble à quelque chose que je devrais être capable d'utiliser le motif regexp match/group pour faire court travail sans parser, mais je n'ai pas de chance pour que l'expression regex fonctionne. Des gourous regexp?

Répondre

5

Essayez

([^=\s]+)\s*=\s*\[\s*([^\s,]+),\s*([^\s,]+)\s*\] 

Cela correspondra une valeur/clé paire et extraire la clé dans backreference 1, la première valeur de 2 backreference et la deuxième valeur dans backreference 3.

En Java cela pourrait ressembler à quelque chose comme ceci:

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); 
} 

Explication:

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

Tim, des explications très utiles. Merci – Sunny

0

Vous pouvez obtenir votre exemple pour travailler en utilisant ce 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('=', ':') 

Mais vous dites que vous pouvez avoir des exemples plus complexes?

La meilleure, solution la plus sûre serait d'obtenir le programme générant la sortie d'utiliser un format de données approprié tel que XML ou JSON

Cependant (bien sûr) ce n'est pas toujours possible

+0

Oui, je l'avais considéré mais malheureusement la chaîne d'entrée est entrée (non approuvée) par l'utilisateur, donc pour des raisons de sécurité c'était un non-go. Merci pour la réponse – Sunny

2

est ici un moyen 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 

qui produit:

[Key1:[val123, val456], Key2:[val78, val123, val666]] 

Te st plate-forme se trouve ici: http://ideone.com/6oFsU

+0

Merci Bart, j'ai combiné votre regexp et Tim à venir avec '([^ = \ s] +) \ s * = \ s * \ [([^]] *)]' Appréciez votre aide – Sunny

+0

@Sunny, vous êtes les bienvenus! –

+0

Il est dommage que '\ S' de Java corresponde aux espaces. :( – tchrist

0

Un bâtiment de façon plus idiomatiques sur la méthode de Bart:

def map = [:] 
("Key1=[val123, val456], Key2=[val78, val123, val666]" =~ /(\S+)=\[([^]]*)]/).each { text, key, value -> 
    map[key] = value.split(/,\s*/) 
} 
Questions connexes