All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.cucumber.cucumberexpressions.TreeRegexp Maven / Gradle / Ivy

There is a newer version: 17.1.0
Show newest version
package io.cucumber.cucumberexpressions;

import java.util.ArrayDeque;
import java.util.Deque;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.IntStream;

/**
 * TreeRegexp represents matches as a tree of {@link Group}
 * reflecting the nested structure of capture groups in the original
 * regexp.
 */
class TreeRegexp {
    private final Pattern pattern;
    private final GroupBuilder groupBuilder;

    TreeRegexp(String regexp) {
        this(Pattern.compile(regexp));
    }

    TreeRegexp(Pattern pattern) {
        this.pattern = pattern;
        char[] chars = pattern.pattern().toCharArray();
        Deque stack = new ArrayDeque<>();

        stack.push(new GroupBuilder());
        char last = 0;
        boolean nonCapturingMaybe = false;
        for (char c : chars) {
            if (c == '(' && last != '\\') {
                stack.push(new GroupBuilder());
                nonCapturingMaybe = false;
            } else if (c == ')' && last != '\\') {
                GroupBuilder gb = stack.pop();
                if (gb.isCapturing()) {
                    stack.peek().add(gb);
                } else {
                    gb.moveChildrenTo(stack.peek());
                }
                nonCapturingMaybe = false;
            } else if (c == '?' && last == '(') {
                nonCapturingMaybe = true;
            } else if (c == ':' && nonCapturingMaybe) {
                stack.peek().setNonCapturing();
                nonCapturingMaybe = false;
            }
            last = c;
        }
        groupBuilder = stack.pop();
    }

    Pattern pattern() {
        return pattern;
    }

    Group match(CharSequence s) {
        Matcher matcher = pattern.matcher(s);
        if (!matcher.matches()) return null;
        return groupBuilder.build(matcher, IntStream.range(0, matcher.groupCount() + 1).iterator());
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy