|
24 | 24 |
|
25 | 25 | @API(status = API.Status.STABLE)
|
26 | 26 | public final class CucumberExpression implements Expression {
|
27 |
| - private static final Pattern ESCAPE_PATTERN = Pattern.compile("[\\\\^\\[({$.|?*+})\\]]"); |
28 |
| - |
| 27 | + /** |
| 28 | + * List of characters to be escaped. |
| 29 | + * The last char is '}' with index 125, so we need only 126 characters. |
| 30 | + */ |
| 31 | + private static final boolean[] CHAR_TO_ESCAPE = new boolean[126]; |
| 32 | + static { |
| 33 | + CHAR_TO_ESCAPE['^'] = true; |
| 34 | + CHAR_TO_ESCAPE['$'] = true; |
| 35 | + CHAR_TO_ESCAPE['['] = true; |
| 36 | + CHAR_TO_ESCAPE[']'] = true; |
| 37 | + CHAR_TO_ESCAPE['('] = true; |
| 38 | + CHAR_TO_ESCAPE[')'] = true; |
| 39 | + CHAR_TO_ESCAPE['{'] = true; |
| 40 | + CHAR_TO_ESCAPE['}'] = true; |
| 41 | + CHAR_TO_ESCAPE['.'] = true; |
| 42 | + CHAR_TO_ESCAPE['|'] = true; |
| 43 | + CHAR_TO_ESCAPE['?'] = true; |
| 44 | + CHAR_TO_ESCAPE['*'] = true; |
| 45 | + CHAR_TO_ESCAPE['+'] = true; |
| 46 | + CHAR_TO_ESCAPE['\\'] = true; |
| 47 | + } |
29 | 48 | private final List<ParameterType<?>> parameterTypes = new ArrayList<>();
|
30 | 49 | private final String source;
|
31 | 50 | private final TreeRegexp treeRegexp;
|
@@ -62,7 +81,17 @@ private String rewriteToRegex(Node node) {
|
62 | 81 | }
|
63 | 82 |
|
64 | 83 | private static String escapeRegex(String text) {
|
65 |
| - return ESCAPE_PATTERN.matcher(text).replaceAll("\\\\$0"); |
| 84 | + int length = text.length(); |
| 85 | + StringBuilder sb = new StringBuilder(length * 2); // prevent resizes |
| 86 | + int maxChar = CHAR_TO_ESCAPE.length; |
| 87 | + for (int i = 0; i < length; i++) { |
| 88 | + char currentChar = text.charAt(i); |
| 89 | + if (currentChar < maxChar && CHAR_TO_ESCAPE[currentChar]) { |
| 90 | + sb.append('\\'); |
| 91 | + } |
| 92 | + sb.append(currentChar); |
| 93 | + } |
| 94 | + return sb.toString(); |
66 | 95 | }
|
67 | 96 |
|
68 | 97 | private String rewriteOptional(Node node) {
|
|
0 commit comments