【问题标题】:how to fill an object based on a query param string?如何根据查询参数字符串填充对象?
【发布时间】:2017-01-02 14:43:35
【问题描述】:

我有这样的字符串:

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

【问题讨论】:

    标签: java regex url java-8


    【解决方案1】:

    您可以将您的模式与| 结合起来,然后查找所有匹配项:

    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
    

    【讨论】:

      【解决方案2】:

      你可以在没有正则表达式的情况下做到这一点。由于您的字符串类似于带有参数的 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.

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-09-24
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 2021-02-04
        • 2011-01-12
        • 1970-01-01
        相关资源
        最近更新 更多