Matcher.java
/*
* (c) Copyright 2021 Hasan Selman Kara. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package li.selman.jpbe.dsl.position;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.MatchResult;
import java.util.regex.Pattern;
import li.selman.jpbe.dsl.token.TokenSequence;
/**
* @author Hasan Selman Kara
*/
final class Matcher {
private Matcher() {
// NO-OP
}
static int positionOfRegex(TokenSequence r, String s, int from, int to) {
if (to < 1 || to > s.length()) throw new IllegalArgumentException("'to' index is invalid.");
if (from < 0 || from >= s.length()) throw new IllegalArgumentException("'from' index is invalid.");
if (from >= to) throw new IllegalArgumentException("'from' index must be smaller than 'to' index.");
List<MatchResult> matches = matches(r.getMergedPattern(), s);
if (matches.isEmpty()) throw new IllegalStateException("No matches found");
int position = 1;
for (MatchResult match : matches) {
int start = match.start();
int end = match.end();
if (inRange(from, to, start, end)) {
return position;
} else {
position++;
}
}
throw new IllegalStateException("No matches");
}
/**
* @return number of matches of {@code r} in {@code s} — 0 if there are none or the {@code r} is empty
*/
static int totalNumberOfMatches(TokenSequence r, String s) {
if (r.getNumberOfTokens() == 0) {
return 0;
}
return matches(r.getMergedPattern(), s).size();
}
private static boolean inRange(int from, int to, int start, int end) {
return from >= start && to <= end;
}
static List<MatchResult> matches(final Pattern p, final CharSequence input) {
final java.util.regex.Matcher matcher = p.matcher(input);
final List<MatchResult> matchResults = new ArrayList<>();
while (matcher.find()) {
matchResults.add(matcher.toMatchResult());
}
return matchResults;
}
}