@Nullable
    private static <T, U> RoutingPredicate<T> parseCompareRoutingPredicate(
            String predicateExpr, Function<String, U> nameConverter,
            BiFunction<U, String, Predicate<T>> equalsPredicate) {
        final Matcher compareMatcher = COMPARE_PATTERN.matcher(predicateExpr);
        if (compareMatcher.matches()) {
            assert compareMatcher.groupCount() == 3;

            final String name = compareMatcher.group(1);
            final String comparator = compareMatcher.group(2);
            final String value = compareMatcher.group(3);

            final Predicate<T> predicate = equalsPredicate.apply(nameConverter.apply(name), value);
            final String noWsValue = WHITESPACE_PATTERN.matcher(value).replaceAll("_");
            switch (comparator) {
                case "=":
                    return eq(name, noWsValue, predicate);
                case "!=":
                    return notEq(name, noWsValue, predicate);
            }
        }
        return null;
    }
Patterns used to parse a given predicate. The predicate can be one of the following forms:
<ul>
    <li>{@code some-name=some-value} which means that the request must have a
    {@code some-name=some-value} header or parameter</li>
    <li>{@code some-name!=some-value} which means that the request must not have a
    {@code some-name=some-value} header or parameter</li>
    <li>{@code some-name} which means that the request must contain a {@code some-name} header or
    parameter</li>
    <li>{@code !some-name} which means that the request must not contain a {@code some-name} header or
    parameter</li>
    <li>{@code some-name=some-value || some-other-value} which means that the request must have
    a {@code some-name=some-value} or a {@code some-other-value} header or parameter</li>
</ul>
core/src/main/java/com/linecorp/armeria/server/RoutingPredicate.java