1 package com.atlassian.plugin.util;
2
3 import com.atlassian.annotations.Internal;
4
5 import java.util.Collection;
6
7 /**
8 * Utility functions for constructing regular expressions.
9 *
10 * The methods here take and return strings to facilitate composing operations without
11 * needing to compile temporary patterns.
12 */
13 @Internal
14 public class RegularExpressions {
15 /**
16 * Obtain a regular expression which matches any one of a given collection of expressions.
17 *
18 * If the provided collection is empty, a regular expression which matches no string (not even
19 * the empty string) is returned.
20 *
21 * @param expressions the individual expressions to compose.
22 * @return an expression which matches when any one of expressions matches.
23 */
24 public static String anyOf(final Collection<String> expressions) {
25 if (expressions.isEmpty()) {
26 // Nothing matches "Something followed by start of string"
27 return ".\\A";
28 } else {
29 // We're going to construct the following expression - spaces added for clarity, <i> are
30 // the expressions:
31 // (?:(?: <0> )|(?: <1> )|(?: <2> ... )|(?: <n-1> ))
32 // Figure out how big the resulting expression will be - break first 6 up as 1 + 5 which
33 // is what the loop below does also:
34 // ( ?:(?: <0> )|(?: <1> )|(?: <2> ... )|(?: <n-1> ))
35 int capacity = 1 + 5 * expressions.size() + 2;
36 for (final String expression : expressions) {
37 capacity += expression.length();
38 }
39 // Now construct the compound regular expression
40 final StringBuilder compound = new StringBuilder(capacity);
41 compound.append('(');
42 for (final String expression : expressions) {
43 compound.append(")|(?:");
44 compound.append(expression);
45 }
46 compound.append("))");
47 // Now compound starts ()|(?: and we want (?:(?:
48 compound.setCharAt(1, '?');
49 compound.setCharAt(2, ':');
50 return compound.toString();
51 }
52 }
53 }