【问题标题】:Java regex: Repeating capturing groupsJava 正则表达式:重复捕获组
【发布时间】:2011-10-19 20:26:30
【问题描述】:

项目是一个或多个数字或字符字符串的逗号分隔列表,例如

"12"
"abc"
"12,abc,3"

我正在尝试匹配 Java 中包含零个或多个项目的括号列表,例如

""
"(12)"
"(abc,12)"
"(abc,12),(30,asdf)"
"(qqq,pp),(abc,12),(30,asdf,2),"

最后一个例子应该分别返回以下匹配组

qqq,pp
abc,12
30,asdf,2

我想出了以下(不正确的)模式

\((.+?)\)(?:,\((.+?)\))*

最后一个例子只匹配以下内容

qqq,pp
30,asdf,2

提示?谢谢

【问题讨论】:

  • 你能把字符串拆分成 "),(" 并去掉剩下的括号来达到你的效果吗?
  • 绝对想要Matcher.find()

标签: java regex


【解决方案1】:

没错。 Java 正则表达式中不能有“可变”数量的捕获组。您的模式有两组:

\((.+?)\)(?:,\((.+?)\))*
  |___|        |___|
 group 1      group 2

每个组将包含该组的最后一场比赛的内容。即,abc,12 将被 30,asdf,2 覆盖。

相关问题:

解决方案是使用一个表达式(类似于\((.+?)\))并使用matcher.find 来迭代匹配项。

【讨论】:

  • 好吧,谢谢,我不知道,现在我得想出一个替代方案
  • 是的。这肯定很烦人。 .net 具有该功能(如我链接到的问题/答案所示。)
  • @David,如果你错过了,他已经给了你一个不错的选择:)
【解决方案2】:

您可以在循环中使用像([^,]+) 这样的正则表达式,或者只使用str.split(",") 来一次获取所有元素。这个版本:str.split("\\s*,\\s*") 甚至允许空格。

【讨论】:

    【解决方案3】:

    (^|\s+)(\S*)(($|\s+)\2)+ 带有忽略大小写选项 /i

    她现在离开了 LEFT LEFT

    此处的示例 - https://regex101.com/r/FEmXui/2

    Match 1
    Full match  3-23    ` left LEft leFT LEFT`
    Group 1.    3-4 ` `
    Group 2.    4-8 `left`
    Group 3.    18-23   ` LEFT`
    Group 4.    18-19   ` `
    

    【讨论】:

      【解决方案4】:

      这可能是解决方案:

      package com.drl.fw.sch;
      
      import java.util.regex.Pattern;
      
      public class AngularJSMatcher extends SimpleStringMatcher  {
      
      Matcher delegate;
      
      
      public AngularJSMatcher(String lookFor){
          super(lookFor);
          // ng-repeat 
          int ind = lookFor.indexOf('-');
          if(ind >= 0 ){
              StringBuilder sb = new StringBuilder();
              boolean first = true;
              for (String s : lookFor.split("-")){
                  if(first){
                      sb.append(s);
                      first = false;
                  }else{
                      if(s.length() >1){
                          sb.append(s.substring(0,1).toUpperCase());
                          sb.append(s.substring(1));
      
                      }else{
                          sb.append(s.toUpperCase());
                      }
                  }
              }
              delegate = new SimpleStringMatcher(sb.toString());
          }else {
              String words[] = lookFor.split("(?<!(^|[A-Z]))(?=[A-Z])|(?<!^)(?=[A-Z][a-z])");
              if(words.length > 1 ){
                  StringBuilder sb = new StringBuilder();
                  for (int i=0;i < words.length;i++) {
                      sb.append(words[i].toLowerCase());
                      if(i < words.length-1) sb.append("-");
                  }
                  delegate = new SimpleStringMatcher(sb.toString());
              }
      
          }
      
      }
      
      @Override
      public boolean match(String in) {
          if(super.match(in)) return true;
          if(delegate != null && delegate.match(in)) return true;
      
          return false;
      }
      
      public static void main(String[] args){
          String lookfor="ngRepeatStart";
      
          Matcher matcher = new AngularJSMatcher(lookfor);
      
          System.out.println(matcher.match( "<header ng-repeat-start=\"item in items\">"));
          System.out.println(matcher.match( "var ngRepeatStart=\"item in items\">"));
      
      }
      

      }

      【讨论】:

        猜你喜欢
        • 2017-09-13
        • 2011-03-11
        • 2017-01-07
        • 2019-12-19
        • 1970-01-01
        • 2010-11-19
        • 1970-01-01
        • 1970-01-01
        • 2013-07-31
        相关资源
        最近更新 更多