Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
609 views
in Technique[技术] by (71.8m points)

regex - Java Pattern print capturing groups

((d{1,2})/(d{1,2})/(d{2,4}))

Is there a way to retrieve a list of all the capture groups with the Pattern object. I debugged the object and all it says is how many groups there are (5).

I need to retrieve a list of the following capture groups.

Example of output:

0 ((d{1,2})/(d{1,2})/(d{2,4}))
1 (d{2})/(d{2})/(d{4})
2 d{2}
3 d{2}
4 d{4}

Update:

I am not necessarily asking if a regular expression exists, but that would be most favorable. So far I have created a rudimentary parser (I do not check for most out-of-bounds conditions) that only matches inner-most groups. I would like to know if there is a way to hold reference to already-visited parenthesis. I would probably have to implement a tree structure?

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class App {

    public final char S = '(';
    public final char E = ')';
    public final char X = '\';

    String errorMessage = "Malformed expression: ";

    /**
     * Actual Output:
     *    Groups: [(//), (d{1,2}), (d{1,2}), (d{2,4})]
     * Expected Output:
     *    Groups: [\b((\d{1,2})/(\d{1,2})/(\d{2,4}))\b, ((\d{1,2})/(\d{1,2})/(\d{2,4})), (d{1,2}), (d{1,2}), (d{2,4})]
     */

    public App() {
        String expression = "\b((\d{1,2})/(\d{1,2})/(\d{2,4}))\b";
        String output = "";

        if (isValidExpression(expression)) {
            List<String> groups = findGroups(expression);
            output = "Groups: " + groups;
        } else {
            output = errorMessage;
        }

        System.out.println(output);
    }

    public List<String> findGroups(String expression) {
        List<String> groups = new ArrayList<>();
        int[] pos;
        int start;
        int end;
        String sub;
        boolean done = false;

        while (expression.length() > 0 && !done) {
            pos = scanString(expression);
            start = pos[0];
            end = pos[1];

            if (start == -1 || end == -1) {
                done = true;
                continue;
            }

            sub = expression.substring(start, end);
            expression = splice(expression, start, end);
            groups.add(0, sub);
        }

        return groups;
    }

    public int[] scanString(String str) {
        int[] range = new int[] { -1, -1 };
        int min = 0;
        int max = str.length() - 1;
        int start = min;
        int end = max;
        char curr;

        while (start <= max) {
            curr = str.charAt(start);
            if (curr == S) {
                range[0] = start;
            }
            start++;
        }

        end = range[0];

        while (end > -1 && end <= max) {
            curr = str.charAt(end);
            if (curr == E) {
                range[1] = end + 1;
                break;
            }

            end++;
        }

        return range;
    }

    public String splice(String str, int start, int end) {
        if (str == null || str.length() < 1)
            return "";

        if (start < 0 || end > str.length()) {
            System.err.println("Positions out of bounds.");
            return str;
        }

        if (start >= end) {
            System.err.println("Start must not exceed end.");
            return str;
        }

        String first = str.substring(0, start);
        String last = str.substring(end, str.length());

        return first + last;
    }

    public boolean isValidExpression(String expression) {
        try {
            Pattern.compile(expression);
        } catch (PatternSyntaxException e) {
            errorMessage += e.getMessage();
            return false;
        }

        return true;
    }

    public static void main(String[] args) {
        new App();
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Here is my solution ... I simply provided a regex of the regex as @SotiriosDelimanolis commented out.

public static void printGroups() {
        String sp = "((\(\\d\{1,2\}\))\/(\(\\d\{1,2\}\))\/(\(\\d\{2,4\}\)))";
        Pattern p = Pattern.compile(sp);
        Matcher m = p.matcher("(\d{1,2})/(\d{1,2})/(\d{2,4})");
        if (m.matches())
            for (int i = 0; i <= m.groupCount(); i++)
                System.out.println(m.group(i));
    }

Pay attention that you cannot remove the if-statement because in order to use the group method you should call the matches method first (I didn't know it!). See this link as a reference about it.

Hope this is what you were asking for ...


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...