Skip to content

Commit fc311df

Browse files
committed
Support full regular expression on PatterMatcher.match()
1 parent dcd1ac8 commit fc311df

File tree

2 files changed

+89
-3
lines changed

2 files changed

+89
-3
lines changed

spring-batch-infrastructure/src/main/java/org/springframework/batch/support/PatternMatcher.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2021 the original author or authors.
2+
* Copyright 2006-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,13 +19,15 @@
1919
import java.util.Comparator;
2020
import java.util.List;
2121
import java.util.Map;
22+
import java.util.regex.Pattern;
2223

2324
import org.springframework.util.Assert;
2425

2526
/**
2627
* @author Dave Syer
2728
* @author Dan Garrette
2829
* @author Marten Deinum
30+
* @author Injae Kim
2931
*/
3032
public class PatternMatcher<S> {
3133

@@ -180,6 +182,19 @@ public static boolean match(String pattern, String str) {
180182
return true;
181183
}
182184

185+
/**
186+
* Tests whether or not a string matches against a regular expression.
187+
* @param regex regular expression to match against. Must not be {@code null}.
188+
* @param str string which must be matched against the regular expression. Must not be {@code null}.
189+
* @return {@code true} if the string matches against the regular expression, or {@code false} otherwise.
190+
*/
191+
public static boolean matchRegex(String regex, String str) {
192+
Assert.notNull(regex, "Regex must not be null");
193+
Assert.notNull(str, "Str must not be null");
194+
195+
return Pattern.matches(regex, str);
196+
}
197+
183198
/**
184199
* <p>
185200
* This method takes a String key and a map from Strings to values of any type. During
@@ -202,12 +217,23 @@ public S match(String line) {
202217
Assert.notNull(line, "A non-null key must be provided to match against.");
203218

204219
for (String key : sorted) {
205-
if (PatternMatcher.match(key, line)) {
220+
if (match(key, line)) {
206221
value = map.get(key);
207222
break;
208223
}
209224
}
210225

226+
if (value == null) {
227+
for (String key : sorted) {
228+
try {
229+
if (matchRegex(key, line)) {
230+
value = map.get(key);
231+
break;
232+
}
233+
} catch (Throwable ignored) {}
234+
}
235+
}
236+
211237
if (value == null) {
212238
throw new IllegalStateException("Could not find a matching pattern for key=[" + line + "]");
213239
}

spring-batch-infrastructure/src/test/java/org/springframework/batch/support/PatternMatcherTests.java

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2006-2022 the original author or authors.
2+
* Copyright 2006-2023 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -22,11 +22,13 @@
2222

2323
import java.util.HashMap;
2424
import java.util.Map;
25+
import java.util.regex.PatternSyntaxException;
2526

2627
import org.junit.jupiter.api.Test;
2728

2829
/**
2930
* @author Dan Garrette
31+
* @author Injae Kim
3032
* @since 2.0
3133
*/
3234
class PatternMatcherTests {
@@ -37,6 +39,7 @@ class PatternMatcherTests {
3739
map.put("an*", 3);
3840
map.put("a*", 2);
3941
map.put("big*", 4);
42+
map.put("bcd.*", 5);
4043
}
4144

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

55+
private static final Map<String, Integer> regexMap = new HashMap<>();
56+
57+
static {
58+
regexMap.put("abc.*", 1);
59+
regexMap.put("a...e", 2);
60+
regexMap.put("123.[0-9][0-9]\\d", 3);
61+
regexMap.put("*............", 100); // invalid regex format
62+
}
63+
5264
@Test
5365
void testMatchNoWildcardYes() {
5466
assertTrue(PatternMatcher.match("abc", "abc"));
@@ -104,6 +116,29 @@ void testMatchStarNo() {
104116
assertFalse(PatternMatcher.match("a*c", "abdeg"));
105117
}
106118

119+
@Test
120+
void testMatchRegex() {
121+
assertTrue(PatternMatcher.matchRegex("abc.*", "abcde"));
122+
}
123+
124+
@Test
125+
void testMatchRegex_notMatched() {
126+
assertFalse(PatternMatcher.matchRegex("abc.*", "cdefg"));
127+
assertFalse(PatternMatcher.matchRegex("abc.", "abcde"));
128+
}
129+
130+
@Test
131+
void testMatchRegex_thrown_invalidRegexFormat() {
132+
assertThrows(PatternSyntaxException.class, () -> PatternMatcher.matchRegex("*..", "abc"));
133+
}
134+
135+
@Test
136+
void testMatchRegex_thrown_notNullParam() {
137+
assertThrows(IllegalArgumentException.class, () -> PatternMatcher.matchRegex("regex", null));
138+
assertThrows(IllegalArgumentException.class, () -> PatternMatcher.matchRegex(null, "str"));
139+
}
140+
141+
107142
@Test
108143
void testMatchPrefixSubsumed() {
109144
assertEquals(2, new PatternMatcher<>(map).match("apple").intValue());
@@ -119,6 +154,11 @@ void testMatchPrefixUnrelated() {
119154
assertEquals(4, new PatternMatcher<>(map).match("biggest").intValue());
120155
}
121156

157+
@Test
158+
void testMatchByRegex() {
159+
assertEquals(5, new PatternMatcher<>(map).match("bcdef12345").intValue());
160+
}
161+
122162
@Test
123163
void testMatchPrefixNoMatch() {
124164
PatternMatcher<Integer> matcher = new PatternMatcher<>(map);
@@ -140,4 +180,24 @@ void testMatchPrefixDefaultValueNoMatch() {
140180
assertEquals(1, new PatternMatcher<>(defaultMap).match("bat").intValue());
141181
}
142182

183+
@Test
184+
void testMatchRegexPrefix() {
185+
assertEquals(1, new PatternMatcher<>(regexMap).match("abcdefg").intValue());
186+
}
187+
188+
@Test
189+
void testMatchRegexWildCards() {
190+
assertEquals(2, new PatternMatcher<>(regexMap).match("a123e").intValue());
191+
}
192+
193+
@Test
194+
void testMatchRegexDigits() {
195+
assertEquals(3, new PatternMatcher<>(regexMap).match("123-789").intValue());
196+
}
197+
198+
@Test
199+
void testMatchRegexNotMatched() {
200+
assertThrows(IllegalStateException.class, () -> new PatternMatcher<>(regexMap).match("Hello world!"));
201+
}
202+
143203
}

0 commit comments

Comments
 (0)