String matching functions
There is a frequent requirement to match strings, either against a constant value or against a pattern involving
wildcard characters or regular expressions.
The string-matcher
library allows string comparisons to be defined in a number of ways, from simple matching for
equality, case-insensitive matching, wildcard matching, regular expression matching or any combination of those forms.
As an example, suppose you want to filter a set of files by name. The function could look something like this:
public void processFiles(List<File> list, StringMatcher filter) {
for (File file : list) {
if (filter.matches(file.getName())) {
// process file
}
}
}
The caller could supply, for example, a wildcard pattern:
processFiles(fileList, StringMatcher.wildcard("File*.txt"));
Or a list of strings:
processFiles(fileList, StringMatcher.alternate("File1.txt", "File2.txt"));
Or even a combination or the two:
processFiles(fileList, StringMatcher.alternate(
StringMatcher.wildcard("File*.txt"),
StringMatcher.simple("README.txt")
));
The StringMatcher
interface specifies a single function:
- boolean matches(CharSequence target)
This does exactly what would be expected; it returns true
if the supplied string (specified as a CharSequence
, so a
String
, a StringBuilder
or any other class that implements CharSequence
may be used) matches the conditions of the
StringMatcher
.
The interface also specifies a number of static functions to create the various types of implementing class:
static SimpleMatcher simple(String string)
(creates aSimpleMatcher
)static CaseInsensitiveMatcher caseInsensitive(String string)
(creates aCaseInsensitiveMatcher
)static ContainsMatcher contains(String pattern)
(creates aContainsMatcher
)static StartsWithMatcher startsWith(String pattern)
(creates aStartsWithMatcher
)static EndsWithMatcher endsWith(String pattern)
(creates aEndsWithMatcher
)static WildcardMatcher wildcard(String pattern)
(creates aWildcardMatcher
)static WildcardMatcher wildcard(String pattern, char singleMatchChar, char multiMatchChar)
(creates aWildcardMatcher
with the specified pattern characters)static PatternMatcher pattern(Pattern pattern)
(creates aPatternMatcher
)static AlternateMatcher alternate(StringMatcher ... matchers)
(creates anAlternateMatcher
)static AlternateMatcher alternate(String ... strings)
(creates anAlternateMatcher
with aSimpleMatcher
for each string)
StringMatcher
is a functional interface, so a lambda taking a CharSequence
and returning a boolean
may be used
wherever a SringMatcher
is called for.
This is the simplest form of StringMatcher
; it performs a comparison with a given String
.
StringMatcher matcher = new SimpleMatcher("Exact match");
The SimpleMatcher
may also be created by StringMatcher.simple(string)
.
This is the same as SimpleMatcher
except that it performs a case-insensitive comparison.
StringMatcher matcher = new CaseInsensitiveMatcher("test");
The CaseInsensitiveMatcher
may also be created by StringMatcher.caseInsensitive(string)
.
The ContainsMatcher
tests whether the string under test contains a given substring.
StringMatcher matcher = new ContainsMatcher("substring");
Note: the functionality of ContainsMatcher
(and StartsWithMatcher
and EndsWithMatxher
below) can be achieved by
using WildcardMatcher
, but it is often clearer to use these explicit forms of StringMatcher
(they are also slightly
more efficient).
The ContainsMatcher
may also be created by StringMatcher.contains(string)
.
The StartsWithMatcher
tests whether the string under test starts with a given substring.
StringMatcher matcher = new StartsWithMatcher("prefix");
The StartsWithMatcher
may also be created by StringMatcher.startsWith(string)
.
The EndsWithMatcher
tests whether the string under test ends with a given substring.
StringMatcher matcher = new EndsWithMatcher("suffix");
The EndsWithMatcher
may also be created by StringMatcher.endsWith(string)
.
This form of StringMatcher
performs a standard “wildcard&rdqio; match, where a “?
” will match any
single character, and a “*
” will match zero or more characters.
StringMatcher matcher = new WildcardMatcher("File*.txt");
It is also possible to specify alternative characters to be used in place of the standard matching characters.
For example, to create a WildcardMatcher
that uses the SQL wildcard characters:
StringMatcher matcher = new WildcardMatcher("File_.%", '_', '%');
The WildcardMatcher
may also be created by StringMatcher.wildcard(pattern)
.
This form of StringMatcher
brings the full power of regular expressions to the matching function:
StringMatcher matcher = new PatternMatcher(Pattern.compile("^File[0-9]{1,3}$"));
The PatternMatcher
may also be created by StringMatcher.pattern(pattern)
.
The AlternateMatcher
allows a set of alternate matchers to be specified:
StringMatcher exactMatcher = new SimpleMatcher("README.txt");
StringMatcher fileMatcher = new WildcardMatcher("File*.txt");
StringMatcher matcher = new AlternateMatcher(exactMatcher, fileMatcher);
The AlternateMatcher
may also be created by StringMatcher.alternate(matcher, matcher)
(supplying a set of
StringMatcher
) or StringMatcher.alternate(string, string)
(which will convert each string to a SimpleMatcher
).
The latest version of the library is 1.1, and it may be obtained from the Maven Central repository.
<dependency>
<groupId>io.jstuff</groupId>
<artifactId>string-matcher</artifactId>
<version>1.1</version>
</dependency>
implementation 'io.jstuff:string-matcher:1.1'
implementation("io.jstuff:string-matcher:1.1")
Peter Wall
2025-03-04