2017-01-02 5 views
-1

私はそのような文字列があります:私は正規表現を使用しますが、私があればそこに疑問に思ったクエリのパラメータ文字列に基づいてオブジェクトを埋める方法は?

パブリッククラスRule {

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

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

私はこのように作成されたオブジェクトを塗りつぶしたいのそうするよりエレガントな方法ですか?

@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.

関連する問題