【问题标题】:Splitting A String In Java?在Java中拆分字符串?
【发布时间】:2017-02-25 19:18:06
【问题描述】:

这是在 Java 7 中

我不知道正则表达式,所以我想知道是否有人知道我如何使用 split 方法从字符串中取出所有用户名:

{tchristofferson=10, mchristofferson=50}

然后将用户名添加到 String[] 数组?这些只是其中的两个用户名,但我希望这适用于无数用户名。

用户名需要以下格式:

3-16个字符,无空格,大小写A-Z和0-9,唯一特殊字符是_(下划线)。

【问题讨论】:

  • 用户名中的有效字符是什么?是否可以包含数字和特殊字符,如_-等。
  • 你应该使用哪个版本的java来完成这个任务?
  • 我在 java 7 中这样做
  • 用户名有这些要求:3-16个字符,不能有空格,A-Z大小写和0-9,只有特殊字符是_(下划线)。

标签: java arrays regex string split


【解决方案1】:

这看起来像 JSON,所以“正确”的答案可能是使用 JSON 解析器。如果这不是一个选项,您可以删除封闭的{},根据", " 拆分字符串,然后根据= 符号拆分每个字符串,取第一项:

String input = "{tchristofferson=10, mchristofferson=50}";
List<String> users =
    Arrays.stream(input.substring(1, input.length() - 1).split(", "))
          .map(s -> s.split("=")[0])
          .collect(Collectors.toList());

【讨论】:

  • 这不是有效的 JSON:JSON 应该在字符串值周围加上引号(严格来说,键名也是如此)。大多数解析器会拒绝这个输入。
  • 其实 JSON 应该有冒号而不是等号
  • Pattern#splitAsStream 可能更简洁。
【解决方案2】:

这是错误的(工作保障)方式:

String[] usernames = str.substring(1)
                        .split("=\\d+[,}]\\s*");

为什么这是错误的方式?我们正在扔掉我们不想要的东西。 第一个字符(不管它是什么),并希望 "=#, " 和 "=#}" 是我们唯一不想要的东西。 如果字符串以"{ tchristofferson=10" 开头,那么第一个用户名将有一个前导空格。

更好的方法是匹配你想要的东西。现在我不想在 iPhone 屏幕上创建答案,这里是:

    String input = "{tchristofferson=10, mchristofferson=50}";

    Pattern USERNAME_VALUE = Pattern.compile("(\\w+)=(\\d+)");
    Matcher matcher = USERNAME_VALUE.matcher(input);

    ArrayList<String> list = new ArrayList<>();
    while(matcher.find()) {
        list.add(matcher.group(1));
    }
    String[] usernames = list.toArray(new String[0]);

这假定您的用户名的每个字符都匹配 \w 模式(即 [a-zA-Z0-9_] 和其他字母数字 Unicode 代码点)。如果您的用户名要求更多/更少限制,请修改。

(\w+)用于捕获用户名matcher.group(1),添加到列表中,最终变成你的String[]

(\d+) 也被用于捕获与此用户关联的号码为matcher.group(2)。此捕获组(目前)未使用,因此您可以删除括号以获得小的效率增益,即"(\\w+)=\\d+"。我将它包括在内,以防您也想对这些值做一些事情。

【讨论】:

    【解决方案3】:

    如果 username 包含 数字= 等特殊字符,则:

    String str = "tchristofferson=10,mchristofferson=50";    
    Pattern ptn = Pattern.compile(",");
    String[] usernames = ptn.split(str); 
    

    【讨论】:

      【解决方案4】:

      你可以尝试在没有 (^) 一个单词 (A-Za-z) 时进行拆分:

      String[] tokens = test.split("[^A-Za-z]");
      

      如果不介意使用列表,请按照@Mureinik 的建议尝试:

          List<String> tokens2 = Arrays.stream(test.split("[^A-Za-z]"))
                  .distinct()
                  .filter(w -> !w.isEmpty())
                  .collect(Collectors.toList());
      

      编辑1

      如果列表包含数字,请尝试:

      String[] tokens = test.split("[^A-Za-z\w]");

      如果你想尝试正则表达式,我强烈推荐这个网站:

      http://regexr.com/

      【讨论】:

      • 如果用户名可能包含数字,我该怎么做?
      • [^A-Za-z\\w] 等价于[^\\w],也就是等价于\W。这给出了["", "tchristofferson", "10", "", "mchristofferson", "50"] 的输出,其中"""10""""50" 不是用户名。
      猜你喜欢
      • 2015-03-30
      • 2012-03-21
      • 2013-02-07
      • 1970-01-01
      • 2014-05-27
      • 1970-01-01
      相关资源
      最近更新 更多