Skip to content

Commit

Permalink
Support full regular expression on PatterMatcher.match()
Browse files Browse the repository at this point in the history
  • Loading branch information
injae-kim committed Nov 19, 2023
1 parent dcd1ac8 commit fc311df
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2021 the original author or authors.
* Copyright 2006-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,13 +19,15 @@
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

import org.springframework.util.Assert;

/**
* @author Dave Syer
* @author Dan Garrette
* @author Marten Deinum
* @author Injae Kim
*/
public class PatternMatcher<S> {

Expand Down Expand Up @@ -180,6 +182,19 @@ public static boolean match(String pattern, String str) {
return true;
}

/**
* Tests whether or not a string matches against a regular expression.
* @param regex regular expression to match against. Must not be {@code null}.
* @param str string which must be matched against the regular expression. Must not be {@code null}.
* @return {@code true} if the string matches against the regular expression, or {@code false} otherwise.
*/
public static boolean matchRegex(String regex, String str) {
Assert.notNull(regex, "Regex must not be null");
Assert.notNull(str, "Str must not be null");

return Pattern.matches(regex, str);
}

/**
* <p>
* This method takes a String key and a map from Strings to values of any type. During
Expand All @@ -202,12 +217,23 @@ public S match(String line) {
Assert.notNull(line, "A non-null key must be provided to match against.");

for (String key : sorted) {
if (PatternMatcher.match(key, line)) {
if (match(key, line)) {
value = map.get(key);
break;
}
}

if (value == null) {
for (String key : sorted) {
try {
if (matchRegex(key, line)) {
value = map.get(key);
break;
}
} catch (Throwable ignored) {}
}
}

if (value == null) {
throw new IllegalStateException("Could not find a matching pattern for key=[" + line + "]");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2006-2022 the original author or authors.
* Copyright 2006-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,11 +22,13 @@

import java.util.HashMap;
import java.util.Map;
import java.util.regex.PatternSyntaxException;

import org.junit.jupiter.api.Test;

/**
* @author Dan Garrette
* @author Injae Kim
* @since 2.0
*/
class PatternMatcherTests {
Expand All @@ -37,6 +39,7 @@ class PatternMatcherTests {
map.put("an*", 3);
map.put("a*", 2);
map.put("big*", 4);
map.put("bcd.*", 5);
}

private static final Map<String, Integer> defaultMap = new HashMap<>();
Expand All @@ -49,6 +52,15 @@ class PatternMatcherTests {
defaultMap.put("*", 1);
}

private static final Map<String, Integer> regexMap = new HashMap<>();

static {
regexMap.put("abc.*", 1);
regexMap.put("a...e", 2);
regexMap.put("123.[0-9][0-9]\\d", 3);
regexMap.put("*............", 100); // invalid regex format
}

@Test
void testMatchNoWildcardYes() {
assertTrue(PatternMatcher.match("abc", "abc"));
Expand Down Expand Up @@ -104,6 +116,29 @@ void testMatchStarNo() {
assertFalse(PatternMatcher.match("a*c", "abdeg"));
}

@Test
void testMatchRegex() {
assertTrue(PatternMatcher.matchRegex("abc.*", "abcde"));
}

@Test
void testMatchRegex_notMatched() {
assertFalse(PatternMatcher.matchRegex("abc.*", "cdefg"));
assertFalse(PatternMatcher.matchRegex("abc.", "abcde"));
}

@Test
void testMatchRegex_thrown_invalidRegexFormat() {
assertThrows(PatternSyntaxException.class, () -> PatternMatcher.matchRegex("*..", "abc"));
}

@Test
void testMatchRegex_thrown_notNullParam() {
assertThrows(IllegalArgumentException.class, () -> PatternMatcher.matchRegex("regex", null));
assertThrows(IllegalArgumentException.class, () -> PatternMatcher.matchRegex(null, "str"));
}


@Test
void testMatchPrefixSubsumed() {
assertEquals(2, new PatternMatcher<>(map).match("apple").intValue());
Expand All @@ -119,6 +154,11 @@ void testMatchPrefixUnrelated() {
assertEquals(4, new PatternMatcher<>(map).match("biggest").intValue());
}

@Test
void testMatchByRegex() {
assertEquals(5, new PatternMatcher<>(map).match("bcdef12345").intValue());
}

@Test
void testMatchPrefixNoMatch() {
PatternMatcher<Integer> matcher = new PatternMatcher<>(map);
Expand All @@ -140,4 +180,24 @@ void testMatchPrefixDefaultValueNoMatch() {
assertEquals(1, new PatternMatcher<>(defaultMap).match("bat").intValue());
}

@Test
void testMatchRegexPrefix() {
assertEquals(1, new PatternMatcher<>(regexMap).match("abcdefg").intValue());
}

@Test
void testMatchRegexWildCards() {
assertEquals(2, new PatternMatcher<>(regexMap).match("a123e").intValue());
}

@Test
void testMatchRegexDigits() {
assertEquals(3, new PatternMatcher<>(regexMap).match("123-789").intValue());
}

@Test
void testMatchRegexNotMatched() {
assertThrows(IllegalStateException.class, () -> new PatternMatcher<>(regexMap).match("Hello world!"));
}

}

0 comments on commit fc311df

Please sign in to comment.