2017-01-02 49 views
-1

我有一個字符串這樣的:如何根據查詢參數字符串填充對象?

//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200 

我要填補我這樣創建的對象:

公共類規則{

public List<String> countries; 
public LocalDateTime fromTime; 
public LocalDateTime toTime; 

我用正則表達式,但我想知道是否有是一個更優雅的方式來做到這一點?

@Test 
public void testRegex() throws Exception { 
    Pattern pattern = Pattern.compile(".*?flag\\((\\d+)\\)=true(.*)"); 
    Matcher matcher = pattern.matcher("bbbbbbflag(27)=true 300"); 
    while (matcher.find()) { 
     System.out.println("group 1: " + matcher.group(1)); 
    } 

    pattern = Pattern.compile("(.*?)countryname=([\\w-]+)(.*)"); 
    matcher = pattern.matcher("countryname=brazil "); 
    while (matcher.find()) { 
     System.out.println("group 2: " + matcher.group(2)); 
    } 

    pattern = Pattern.compile(".*?countryname=(.*+)&.*]"); 
    matcher = pattern.matcher("countryname=brazil&bllllll"); 
    while (matcher.find()) { 
     System.out.println("group 1: " + matcher.group(1)); 
    } 

    pattern = Pattern.compile(".*?useryear<=(\\d+)&usermonth<=(\\d+)&userdayofmonth<=(\\d+)(.*)"); 
    matcher = pattern.matcher("useryear<=2017&usermonth<=01&userdayofmonth<=15"); 
    while (matcher.find()) { 
     System.out.println("group 1: " + matcher.group(1)); 
     System.out.println("group 2: " + matcher.group(2)); 
     System.out.println("group 3: " + matcher.group(3)); 
    } 
} 

回答

0

您可以用|結合的模式,然後查找所有比賽:

String s = "//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200\n"; 
Pattern p = Pattern.compile("((countryname)=([\\w-]+)|(useryear)<=(\\d+)|(usermonth)<=(\\d+)|(userdayofmonth)<=(\\d+))"); 
Matcher m = p.matcher(s); 

while(m.find()){ 
    String type = ""; 
    String value = ""; 
    boolean first = true; 

    for(int i = 2; i<=m.groupCount(); i++){ 
     String group = m.group(i); 
     if(first && group != null){ 
      type = group; 
      first = false; 
     }else if(group != null){ 
      value = group; 
      break; 
     } 
    } 

    System.out.println("Type: " + type + " Value: " + value); 
} 

輸出:

Type: countryname Value: Brazil 
Type: useryear Value: 2017 
Type: usermonth Value: 01 
Type: userdayofmonth Value: 15 
0

你可以不用正則表達式。由於你的字符串類似於帶參數的http查詢,我們可以用類似於http查詢的方式解析它。請嘗試,如果這個例子可以幫助你。

package gnu; 

import java.util.*; 
import java.util.stream.Collectors; 
import java.util.AbstractMap.SimpleImmutableEntry; 
import static java.util.stream.Collectors.toList; 

public class Main { 

    public static void main(String[] strg) { 

     String str = "//RULE countryname=Brazil&useryear<=2017&usermonth<=01&userdayofmonth<=15 200"; 
     str = str.substring(str.indexOf(" ")+1, str.lastIndexOf(" ")); 
     try { 
      ParseParams parse = new ParseParams(); 
      Map<String, List<String>> map = parse.parseParams(str); 
      map.entrySet().forEach(entry -> { 
       System.out.println("Key : " + entry.getKey() + " Value : " + entry.getValue()); 
      }); 
     } catch (Throwable t) { 
      t.printStackTrace(); 
     } 
    } 
} 

class ParseParams { 

    Map<String, List<String>> parseParams(String url) { 

     return Arrays.stream(url.split("&")) 
       .map(this::splitQueryParameter) 
       .collect(Collectors.groupingBy(SimpleImmutableEntry::getKey, LinkedHashMap::new, Collectors.mapping(Map.Entry::getValue, toList()))); 
    } 

    private SimpleImmutableEntry<String, String> splitQueryParameter(String it) { 
     final int idx = it.indexOf("="); 
     String key = idx > 0 ? it.substring(0, idx) : it; 
     String value = idx > 0 && it.length() > idx + 1 ? it.substring(idx + 1) : null; 
     if (key.contains("<")) { 
      key = key.replace("<", ""); 
     } 
     return new SimpleImmutableEntry<>(key, value); 
    } 
} 

輸出

Key : countryname Value : [Brazil] 
Key : useryear Value : [2017] 
Key : usermonth Value : [01] 
Key : userdayofmonth Value : [15] 

Online demo.

相關問題