1 /*
2 * Hunt - A refined core library for D programming language.
3 *
4 * Copyright (C) 2018-2019 HuntLabs
5 *
6 * Website: https://www.huntlabs.net/
7 *
8 * Licensed under the Apache-2.0 License.
9 *
10 */
11
12 module hunt.text.PatternMatchUtils;
13
14 import hunt.text.Common;
15
16 import std.range.primitives;
17 import std.string;
18
19 /**
20 * Utility methods for simple pattern matching, in particular for
21 * Spring's typical "xxx*", "*xxx" and "*xxx*" pattern styles.
22 *
23 * @author Juergen Hoeller
24 */
25 abstract class PatternMatchUtils {
26
27 /**
28 * Match a string against the given pattern, supporting the following simple
29 * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
30 * arbitrary number of pattern parts), as well as direct equality.
31 * @param pattern the pattern to match against
32 * @param str the string to match
33 * @return whether the string matches the given pattern
34 */
35 static bool simpleMatch(string pattern, string str) {
36 if (pattern.empty || str.empty) {
37 return false;
38 }
39 ptrdiff_t firstIndex = pattern.indexOf('*');
40 if (firstIndex == -1) {
41 return pattern == str;
42 }
43 if (firstIndex == 0) {
44 if (pattern.length == 1) {
45 return true;
46 }
47 ptrdiff_t nextIndex = pattern.indexOf('*', firstIndex + 1);
48 if (nextIndex == -1) {
49 return str.endsWith(pattern.substring(1));
50 }
51 string part = pattern.substring(1, nextIndex);
52 if ("" == part) {
53 return simpleMatch(pattern.substring(nextIndex), str);
54 }
55 ptrdiff_t partIndex = str.indexOf(part);
56 while (partIndex != -1) {
57 if (simpleMatch(pattern.substring(nextIndex), str.substring(partIndex + part.length))) {
58 return true;
59 }
60 partIndex = str.indexOf(part, partIndex + 1);
61 }
62 return false;
63 }
64 return (str.length >= firstIndex &&
65 pattern.substring(0, firstIndex).equals(str.substring(0, firstIndex)) &&
66 simpleMatch(pattern.substring(firstIndex), str.substring(firstIndex)));
67 }
68
69 /**
70 * Match a string against the given patterns, supporting the following simple
71 * pattern styles: "xxx*", "*xxx", "*xxx*" and "xxx*yyy" matches (with an
72 * arbitrary number of pattern parts), as well as direct equality.
73 * @param patterns the patterns to match against
74 * @param str the string to match
75 * @return whether the string matches any of the given patterns
76 */
77 static bool simpleMatch(string[] patterns, string str) {
78 if (patterns !is null) {
79 foreach (string pattern ; patterns) {
80 if (simpleMatch(pattern, str)) {
81 return true;
82 }
83 }
84 }
85 return false;
86 }
87
88 }