import java.util.regex.Pattern;

class VerbalExpression {
    private String prefixes = "", source = "", suffixes = "", pattern = "";
    private int modifiers = Pattern.MULTILINE;

    public VerbalExpression () {
        this.updatePattern();
    }

    private String sanitize(String value) {
        if(value == null)
            return value;
        return Pattern.quote(value);
    }

    public VerbalExpression add(String value) {
        this.source += value;
        return this.updatePattern();
    }

    public VerbalExpression updatePattern() {
        Pattern p = Pattern.compile(this.prefixes + this.source + this.suffixes, this.modifiers);
        this.pattern = p.pattern();
        return this;
    }

    public VerbalExpression startOfLine(boolean enable) {
        this.prefixes = enable ? "^" : "";
        this.updatePattern();
        return this;
    }

    public VerbalExpression startOfLine() {
        return startOfLine(true);
    }

    public VerbalExpression endOfLine(boolean enable) {
        this.suffixes = enable ? "$" : "";
        this.updatePattern();
        return this;
    }

    public VerbalExpression endOfLine() {
        return endOfLine(true);
    }

    public VerbalExpression then(String value) {
        value = sanitize(value);
        this.add("(" + value + ")");
        return this;
    }

    public VerbalExpression find(String value) {
        this.then(value);
        return this;
    }

    public VerbalExpression maybe(String value) {
        value = sanitize(value);
        this.add("(" + value + ")?");
        return this;
    }

    public VerbalExpression anything() {
        this.add("(.*)");
        return this;
    }

    public VerbalExpression anythingBut(String value) {
        value = sanitize(value);
        this.add("([^" + value + "]*)");
        return this;
    }

    public VerbalExpression something() {
        this.add("(.+)");
        return this;
    }

    public VerbalExpression somethingBut(String value) {
        value = sanitize(value);
        this.add("([^" + value + "]+)");
        return this;
    }

    public VerbalExpression replace(String source, String value) {
        this.updatePattern();
        this.source.replaceAll(pattern,value);
        return this;
    }

    public VerbalExpression lineBreak() {
        this.add("(\\n|(\\r\\n))");
        return this;
    }

    public VerbalExpression br() {
        this.lineBreak();
        return this;
    }

    public VerbalExpression tab() {
        this.add("\\t");
        return this;
    }

    public VerbalExpression word() {
        this.add("\\w+");
        return this;
    }

    public VerbalExpression anyOf(String value) {
        value = sanitize(value);
        this.add("[" + value + "]");
        return this;
    }

    public VerbalExpression any(String value) {
        this.anyOf(value);
        return this;
    }

    public VerbalExpression range(Object[] args) {
        String value = "[";
        for(int _from = 0; _from < args.length; _from += 2) {
            int _to = _from+1;
            if (args.length <= _to) break;
            int from = Integer.getInteger(sanitize((String)args[_from]));
            int to = Integer.getInteger(sanitize((String)args[_to]));

            value += from + "-" + to;
        }

        value += "]";

        this.add(value);
        return this;
    }

    public VerbalExpression addModifier(char modifier) {
        switch (modifier) {
            case 'd':
                modifiers |= Pattern.UNIX_LINES;
                break;
            case 'i':
                modifiers |= Pattern.CASE_INSENSITIVE;
                break;
            case 'x':
                modifiers |= Pattern.COMMENTS;
                break;
            case 'm':
                modifiers |= Pattern.MULTILINE;
                break;
            case 's':
                modifiers |= Pattern.DOTALL;
                break;
            case 'u':
                modifiers |= Pattern.UNICODE_CASE;
                break;
            case 'U':
                modifiers |= Pattern.UNICODE_CHARACTER_CLASS;
                break;
            default:
                break;
        }

        this.updatePattern();
        return this;
    }

    public VerbalExpression removeModifier(char modifier) {
        switch (modifier) {
            case 'd':
                modifiers ^= Pattern.UNIX_LINES;
                break;
            case 'i':
                modifiers ^= Pattern.CASE_INSENSITIVE;
                break;
            case 'x':
                modifiers ^= Pattern.COMMENTS;
                break;
            case 'm':
                modifiers ^= Pattern.MULTILINE;
                break;
            case 's':
                modifiers ^= Pattern.DOTALL;
                break;
            case 'u':
                modifiers ^= Pattern.UNICODE_CASE;
                break;
            case 'U':
                modifiers ^= Pattern.UNICODE_CHARACTER_CLASS;
                break;
            default:
                break;
        }

        this.updatePattern();
        return this;
    }

    public VerbalExpression withAnyCase(boolean enable) {
        if (enable) this.addModifier( 'i' );
        else this.removeModifier( 'i' );
        this.updatePattern();
        return this;
    }

    public VerbalExpression withAnyCase() {
        return withAnyCase(true);
    }

    public VerbalExpression searchOneLine(boolean enable) {
        if (enable) this.removeModifier( 'm' );
        else this.addModifier( 'm' );
        this.updatePattern();
        return this;
    }

    public VerbalExpression multiple(String value) {
        value = this.sanitize(value);
        switch (value.charAt(0)) {
            case '*':
            case '+':
                break;
            default:
                value += '+';
        }
        this.add(value);
        return this;
    }

    public VerbalExpression or(String value) {
        if (this.prefixes.indexOf("(") == -1) this.prefixes += "(";
        if (this.suffixes.indexOf(")") == -1) this.suffixes = ")" + this.suffixes;

        this.add(")|(");
        if (value != null) this.then(value);
        return this;
    }

    public boolean test(String toTest) {
        return Pattern.matches(this.pattern, toTest);
    }

    public String toString() {
        return this.pattern.toString();
    }
}

@@ -24,16 +24,48 @@
 Pattern;
+%0Aimport java.util.regex.Matcher;
 %0A%0Aclass 
@@ -333,87 +333,571 @@
     
-if(value == null)%0A            return value;%0A        return Pattern.quote(value)
+Matcher matcher = Pattern.compile(%22%22).matcher(%22%22).usePattern(Pattern.compile(%22%5B%5E%5C%5Cw%5D%22));%0A        int lastEnd = 0;%0A        String result = %22%22;%0A        matcher.reset(value);%0A        boolean matcherCalled = false;%0A        while (matcher.find()) %7B%0A            matcherCalled = true;%0A            if (matcher.start() != lastEnd) result += value.substring(lastEnd, matcher.start());%0A            result += %22%5C%5C%22 + value.substring(matcher.start(), matcher.end());%0A            lastEnd = matcher.end();%0A        %7D%0A        if (!matcherCalled) return value;%0A        return result
 ;%0A  
@@ -6764,16 +6764,21 @@
 ean test
+Exact
 (String 
@@ -6814,36 +6814,203 @@
 ern.
-matches(this.pattern, toTest
+compile(this.pattern, this.modifiers).matcher(toTest).matches();%0A    %7D%0A%0A    public boolean test(String toTest) %7B%0A        return Pattern.compile(this.pattern, this.modifiers).matcher(toTest).find(
 );%0A 

Fix sanitize() & modifier bugs and add test() & testExact()