2010-11-17 33 views
1

我試圖分析是這樣的: Key1=[val123, val456], Key2=[val78, val123]正規表達式模式幫助Java/Groovy的

Map<String, List<String>> 一個概率是,無論是鍵和值可能有非字母字符NUM像.:-_

這看起來像我應該能夠使用正則表達式模式匹配/組的東西做短暫的工作,而不解析,但我沒有任何運氣得到正則表達式工作。任何正則表達式大師?

回答

5

嘗試

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

添,非常有幫助的說明。謝謝 – Sunny 2010-11-17 20:05:11

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

是的,我已經考慮過這一點,但不幸的是輸入的字符串是(不可信的)用戶輸入,所以出於安全原因,這是一個不行。感謝您的回覆 – Sunny 2010-11-17 20:06:55

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]] 

特ST鑽機可以在這裏找到:http://ideone.com/6oFsU

+0

感謝Bart,我將您的正則表達式和Tim的想法結合起來,提出了'([^ = \ s] +)\ s * = \ s * \ [([^]] *)]'感謝您的協助 – Sunny 2010-11-17 20:03:25

+0

@孫尼,不客氣! – 2010-11-18 00:06:33

+0

Java的'\ S'匹配空格是很遺憾的。 :( – tchrist 2010-12-02 02:05:46

0

更地道的方式建設上Bart的方法:

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