【问题标题】:scanner.useDelimiter() regex javascanner.useDelimiter() 正则表达式 java
【发布时间】:2014-04-12 20:14:57
【问题描述】:

我有一个格式不方便的字符串。这是一个例子:

(Air Fresheners,17)->(Chocolate Chips,14)->(Juice-Frozen,24)

我需要遍历这个字符串并只提取括号中的第一个项目。所以使用上面的 sn-p 作为输入,我希望我的代码返回:

Air Fresheners
Chocolate Chips
Juice-Frozen

请注意,某些项目的项目名称中有-。这些应保留并包含在最终输出中。我试图使用:

Scanner.useDelimiter(insert regex here)

...但我没有运气。完成任务的其他方法都可以,但请保持相对简单。

【问题讨论】:

  • 那么您对Scanner.useDelimiter(...) 做了什么尝试?您是否使用了正确的分隔符 (->)?我认为我们需要查看更多代码来帮助您。
  • 由于范围(例如 a-z),破折号可能是一个特殊字符,所以不妨尝试使用正则表达式“\->”

标签: java regex java.util.scanner delimiter


【解决方案1】:

我知道这是旧的,我不是专家,但你不能使用 replaceAll 吗?如下:

String s = "(Air Fresheners,17)->(Chocolate Chips,14)->(Juice-Frozen,24)".replaceAll("(->)|[\\(\\)]|\\d+","");

for (String str : s.split(","))
{
  System.out.println(str);
}

【讨论】:

    【解决方案2】:

    试试这个

    • 使用正则表达式在)->(的基础上进行拆分

      String s="(Air Fresheners,17)->(Chocolate Chips,14)->(Juice-Frozen,24)";
      
      Pattern regex = Pattern.compile("\\)->\\(");
      Matcher regexMatcher = regex.matcher(s);
      int i=0;
      while (regexMatcher.find()) {
          System.out.println(s.substring(i+1,regexMatcher.start()));
          i=regexMatcher.end()-1;
      }
      System.out.println(s.substring(i+1,s.length()-1));
      
    • 试试String.split()方法

      String s = "(Air Fresheners,17)->(Chocolate Chips,14)->(Juice-Frozen,24)";
      
      for (String str : s.substring(1, s.length() - 1).split("\\)->\\(")) {
          System.out.println(str);
      }
      

    【讨论】:

    • 第二个版本是我见过的最简单的并且效果很好
    【解决方案3】:

    这可以通过正则表达式来完成。我们匹配 ([^,)(]*) 匹配任何不包含括号或逗号的名称,,\\d+\\) 匹配 ,14) 部分,(?:->)? 匹配 可能 -> 在元组之后。我们使用 group(1) 来获取名字(group(0) 返回整个元组(Air Fresheners,17)->

        List<String> ans = new ArrayList<>();
    
        Matcher m = Pattern.compile("\\(([^,)(]*),\\d+\\)(?:->)?").matcher(str);
        while(m.find()){
            String s = m.group(1);
            ans.add(m.group(1));
        }
    

    给定(Air Fresheners,17)-&gt;(Chocolate Chips,14)-&gt;(Juice-Frozen,24),这个程序返回[Air Fresheners, Chocolate Chips, Juice-Frozen]

    【讨论】:

      【解决方案4】:

      (空气清新剂,17)->(巧克力片,14)->(冷冻果汁,24)

      你可以把它想象成介于 ( 和 , 之间的一切

      所以,

      \(.*?\,
      

      将匹配 "(Air Fresheners," (? 是为了让它不贪婪,当它看到逗号时停止)

      因此,如果您热衷于使用正则表达式,那么只需匹配这些,并获取一个子字符串来摆脱 ( 和 ,

      【讨论】:

      • 我尝试将模式复制到我的代码中,如下所示:pairScan.useDelimiter("\(.*?\,"); 用于某些扫描仪pairScan。我收到错误“无效的转义序列(有效的转义序列是 \b \t \n \f \r \" \' \\ )”。我知道 useDelimiter 应该采用比错误中显示的更多的转义序列,任何想法为什么会出现此错误会发生吗?
      • 这主要是关于正则表达式的问题,所以我仍在努力寻找正确的正则表达式来摆脱“(”和“,”
      • 你能告诉我这两个字符(“(”和“,”)的正确表达方式是什么吗?
      • 嗨 Zach,正则表达式要求和 Java 要求之间变得相当棘手... \(.*?\, 是带有反斜杠的正则表达式,因为 ( 和 , 是正则表达式中的特殊字符。Java 没有'不喜欢字符串中的反斜杠,所以你必须在Java中编写“\\(。*?\\,”才能编译它。这很有趣,因为反斜杠也是stackoverflow的特殊字符,所以我'我无法写出我的答案:P
      【解决方案5】:

      我将首先使用)-&gt; 作为分隔符。在每个scanner.next() 上,使用子字符串去掉第一个字符(括号),然后在该字符串上放置第二个扫描器,使用, 作为分隔符。在代码中,这看起来像:

          Scanner s1 = new Scanner(string).useDelimiter("\\s*)->\\s*");
          while(s1.hasNext())
          {
              Scanner s2 = new Scanner(s1.next).useDelimiter("\\s*,\\s*");
              System.out.println(s2.next.substring(1));
          }
      

      【讨论】:

      • 我尝试了这种方法并得到了一个异常:Unmatched closing ')' near index 2 \s*)->\s*
      • 我知道我们想忽略 Scanner 找到的第一个 )。那么为什么它需要一个右括号呢?
      猜你喜欢
      • 2015-12-29
      • 1970-01-01
      • 2016-09-28
      • 2013-01-18
      • 2012-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多