1111 * using heuristics. This is particularly useful for languages that don't have a
1212 * literal syntax for regular expressions. In Java, a regular expression has to be represented as a String.
1313 *
14- * A string that starts with `^` and/or ends with `$` is considered a regular expression.
14+ * A string that starts with `^` and/or ends with `$` (or written in script style, i.e. starting with `/`
15+ * and ending with `/`) is considered a regular expression.
1516 * Everything else is considered a Cucumber expression.
1617 */
1718@ API (status = API .Status .STABLE )
1819public final class ExpressionFactory {
1920
20- private static final Pattern BEGIN_ANCHOR = Pattern .compile ("^\\ ^.*" );
21- private static final Pattern END_ANCHOR = Pattern .compile (".*\\ $$" );
22- private static final Pattern SCRIPT_STYLE_REGEXP = Pattern .compile ("^/(.*)/$" );
2321 private static final Pattern PARAMETER_PATTERN = Pattern .compile ("((?:\\ \\ ){0,2})\\ {([^}]*)\\ }" );
2422
2523 private final ParameterTypeRegistry parameterTypeRegistry ;
@@ -29,14 +27,30 @@ public ExpressionFactory(ParameterTypeRegistry parameterTypeRegistry) {
2927 }
3028
3129 public Expression createExpression (String expressionString ) {
32- if (BEGIN_ANCHOR .matcher (expressionString ).find () || END_ANCHOR .matcher (expressionString ).find ()) {
33- return createRegularExpressionWithAnchors (expressionString );
30+ /* This method is called often (typically about number_of_steps x
31+ * nbr_test_scenarios), thus performance is more important than
32+ * readability here.
33+ * Consequently, we check the first and last expressionString
34+ * characters to determine whether we need to create a
35+ * RegularExpression or a CucumberExpression (because character
36+ * matching is faster than startsWith/endsWith and regexp matching).
37+ */
38+ int length = expressionString .length ();
39+ if (length == 0 ) {
40+ return new CucumberExpression (expressionString , this .parameterTypeRegistry );
3441 }
35- Matcher m = SCRIPT_STYLE_REGEXP .matcher (expressionString );
36- if (m .find ()) {
37- return new RegularExpression (Pattern .compile (m .group (1 )), parameterTypeRegistry );
42+
43+ int lastCharIndex = length - 1 ;
44+ char firstChar = expressionString .charAt (0 );
45+ char lastChar = expressionString .charAt (lastCharIndex );
46+
47+ if (firstChar == '^' || lastChar == '$' ) {
48+ return this .createRegularExpressionWithAnchors (expressionString );
49+ } else if (firstChar == '/' && lastChar == '/' ) {
50+ return new RegularExpression (Pattern .compile (expressionString .substring (1 , lastCharIndex )), this .parameterTypeRegistry );
3851 }
39- return new CucumberExpression (expressionString , parameterTypeRegistry );
52+
53+ return new CucumberExpression (expressionString , this .parameterTypeRegistry );
4054 }
4155
4256 private RegularExpression createRegularExpressionWithAnchors (String expressionString ) {
0 commit comments