Finding all of the matching substrings, not only the “most extended” one

后端 未结 5 1878
甜味超标
甜味超标 2020-12-06 06:02

The code

String s = \"y z a a a b c c z\";
Pattern p = Pattern.compile(\"(a )+(b )+(c *)c\");
Matcher m = p.matcher(s);
while (m.find()) {
    System.out.pri         


        
5条回答
  •  温柔的废话
    2020-12-06 06:27

    Given these very specific constraints (i.e. this is not a general case solution), this will work:

    import java.util.Set;
    import java.util.TreeSet;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    public class test {
    
        public static void main(String[] args) {
    
            String s = "y z a a a b c c z";
    
            Pattern p = Pattern.compile("(a )+(b )+(c ?)+");
            Set set = recurse(s, p, 0);
        }
    
        public static Set recurse(String s, Pattern p, int depth) {
            int temp = depth;
            while(temp>0) {
                System.out.print("  ");
                temp--;
            }
            System.out.println("-> " +s);
    
            Matcher matcher = p.matcher(s);
            Set set = new TreeSet();
    
            if(matcher.find()) {
                String found = matcher.group().trim();
                set.add(found);
                set.addAll(recurse(found.substring(1), p, depth+1));
                set.addAll(recurse(found.substring(0, found.length()-1), p, depth+1));
            }
    
            while(depth>0) {
                System.out.print("  ");
                depth--;
            }
            System.out.println("<- " +s);
            return set;
        }
    }
    

    I'm reasonably sure you can adapt it to work on other cases, but the recursion into the matched string means that overlapping matches (like the one pointed out by @ahenderson) won't work.

提交回复
热议问题