From 576af14b03627caf8c8d9a5127c260020fc4179e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Virkkil=C3=A4?= Date: Sun, 25 Feb 2018 20:53:50 +0200 Subject: [PATCH 1/4] Implement "regex" expression that returns an array of match groups or null if no match. --- .../expression/definitions/index.js | 23 +++++++++++++++++- .../expression-tests/regex/basic/test.json | 24 +++++++++++++++++++ 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 test/integration/expression-tests/regex/basic/test.json diff --git a/src/style-spec/expression/definitions/index.js b/src/style-spec/expression/definitions/index.js index e547731870d..2ce0aef772f 100644 --- a/src/style-spec/expression/definitions/index.js +++ b/src/style-spec/expression/definitions/index.js @@ -533,7 +533,28 @@ CompoundExpression.register(expressions, { StringType, varargs(StringType), (ctx, args) => args.map(arg => arg.evaluate(ctx)).join('') - ] + ], + + 'regex': { + type: array(StringType), + overloads: [ + [ + [StringType, StringType], + (ctx, [r, s]) => { + const m = RegExp(r.evaluate(ctx)).exec(s.evaluate(ctx)); + /* Slice will make a new array without the extra attributes of the match object */ + return (m !== null)? m.slice(): null; + } + ], [ + [StringType, StringType, StringType], + (ctx, [r, f, s]) => { + const m = RegExp(r.evaluate(ctx), f.evaluate(ctx)).exec(s.evaluate(ctx)); + /* Slice will make a new array without the extra attributes of the match object */ + return (m !== null)? m.slice(): null; + } + ] + ] + } }); module.exports = expressions; diff --git a/test/integration/expression-tests/regex/basic/test.json b/test/integration/expression-tests/regex/basic/test.json new file mode 100644 index 00000000000..dc12b2998c7 --- /dev/null +++ b/test/integration/expression-tests/regex/basic/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["regex", ["get", "r"], ["get", "s"]], + "inputs": [ + [{}, {"properties": {"r": ".*", "s": "some string"}}], + [{}, {"properties": {"r": "me stri", "s": "some string"}}], + [{}, {"properties": {"r": "(.*) string", "s": "some string"}}], + [{}, {"properties": {"r": "([eosm]{4}) (string)", "s": "some string"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "array" + }, + "outputs": [ + ["some string"], + ["me stri"], + ["some string", "some"], + ["some string", "some", "string"] + ], + "serialized": ["regex", ["get", "r"], ["get", "s"]] + } +} From 4a9d05946d4d7840b00beb3dd95266b2c6dbf193 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Virkkil=C3=A4?= Date: Tue, 27 Feb 2018 10:26:36 +0200 Subject: [PATCH 2/4] Fix spacing as reported by es lint --- src/style-spec/expression/definitions/index.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/style-spec/expression/definitions/index.js b/src/style-spec/expression/definitions/index.js index 2ce0aef772f..dbb030c9811 100644 --- a/src/style-spec/expression/definitions/index.js +++ b/src/style-spec/expression/definitions/index.js @@ -543,14 +543,14 @@ CompoundExpression.register(expressions, { (ctx, [r, s]) => { const m = RegExp(r.evaluate(ctx)).exec(s.evaluate(ctx)); /* Slice will make a new array without the extra attributes of the match object */ - return (m !== null)? m.slice(): null; + return (m !== null) ? m.slice() : null; } ], [ [StringType, StringType, StringType], (ctx, [r, f, s]) => { const m = RegExp(r.evaluate(ctx), f.evaluate(ctx)).exec(s.evaluate(ctx)); /* Slice will make a new array without the extra attributes of the match object */ - return (m !== null)? m.slice(): null; + return (m !== null) ? m.slice() : null; } ] ] From cf12e8f629c33b71578787539ad07e0a7d721cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Virkkil=C3=A4?= Date: Tue, 27 Feb 2018 10:27:37 +0200 Subject: [PATCH 3/4] Rename "regex" to "regex-match" --- src/style-spec/expression/definitions/index.js | 3 +-- .../expression-tests/{regex => regex-match}/basic/test.json | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) rename test/integration/expression-tests/{regex => regex-match}/basic/test.json (83%) diff --git a/src/style-spec/expression/definitions/index.js b/src/style-spec/expression/definitions/index.js index dbb030c9811..e607696729c 100644 --- a/src/style-spec/expression/definitions/index.js +++ b/src/style-spec/expression/definitions/index.js @@ -534,8 +534,7 @@ CompoundExpression.register(expressions, { varargs(StringType), (ctx, args) => args.map(arg => arg.evaluate(ctx)).join('') ], - - 'regex': { + 'regex-match': { type: array(StringType), overloads: [ [ diff --git a/test/integration/expression-tests/regex/basic/test.json b/test/integration/expression-tests/regex-match/basic/test.json similarity index 83% rename from test/integration/expression-tests/regex/basic/test.json rename to test/integration/expression-tests/regex-match/basic/test.json index dc12b2998c7..417a1e5445f 100644 --- a/test/integration/expression-tests/regex/basic/test.json +++ b/test/integration/expression-tests/regex-match/basic/test.json @@ -1,5 +1,5 @@ { - "expression": ["regex", ["get", "r"], ["get", "s"]], + "expression": ["regex-match", ["get", "r"], ["get", "s"]], "inputs": [ [{}, {"properties": {"r": ".*", "s": "some string"}}], [{}, {"properties": {"r": "me stri", "s": "some string"}}], @@ -19,6 +19,6 @@ ["some string", "some"], ["some string", "some", "string"] ], - "serialized": ["regex", ["get", "r"], ["get", "s"]] + "serialized": ["regex-match", ["get", "r"], ["get", "s"]] } } From d723aaa9c1c17aec94ecbf64a51e8f1f66d1fb58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mikko=20Virkkil=C3=A4?= Date: Tue, 27 Feb 2018 10:28:46 +0200 Subject: [PATCH 4/4] Add regex-test and regex-replace which directly return boolean or string respectively. --- .../expression/definitions/index.js | 24 +++++++++++++++++++ .../regex-replace/basic/test.json | 24 +++++++++++++++++++ .../regex-test/basic/test.json | 24 +++++++++++++++++++ 3 files changed, 72 insertions(+) create mode 100644 test/integration/expression-tests/regex-replace/basic/test.json create mode 100644 test/integration/expression-tests/regex-test/basic/test.json diff --git a/src/style-spec/expression/definitions/index.js b/src/style-spec/expression/definitions/index.js index e607696729c..6a4e6205416 100644 --- a/src/style-spec/expression/definitions/index.js +++ b/src/style-spec/expression/definitions/index.js @@ -534,6 +534,30 @@ CompoundExpression.register(expressions, { varargs(StringType), (ctx, args) => args.map(arg => arg.evaluate(ctx)).join('') ], + 'regex-test': { + type: BooleanType, + overloads: [ + [ + [StringType, StringType], + (ctx, [r, s]) => RegExp(r.evaluate(ctx)).test(s.evaluate(ctx)) + ], [ + [StringType, StringType, StringType], + (ctx, [r, f, s]) => RegExp(r.evaluate(ctx), f.evaluate(ctx)).test(s.evaluate(ctx)) + ] + ] + }, + 'regex-replace': { + type: StringType, + overloads: [ + [ + [StringType, StringType, StringType], + (ctx, [r, n, s]) => s.evaluate(ctx).replace(RegExp(r.evaluate(ctx)), n.evaluate(ctx)) + ], [ + [StringType, StringType, StringType, StringType], + (ctx, [r, f, n, s]) => s.evaluate(ctx).replace(RegExp(r.evaluate(ctx), f.evaluate(ctx)), n.evaluate(ctx)) + ] + ] + }, 'regex-match': { type: array(StringType), overloads: [ diff --git a/test/integration/expression-tests/regex-replace/basic/test.json b/test/integration/expression-tests/regex-replace/basic/test.json new file mode 100644 index 00000000000..6333ba973e6 --- /dev/null +++ b/test/integration/expression-tests/regex-replace/basic/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["regex-replace", ["get", "r"], ["get", "n"], ["get", "s"]], + "inputs": [ + [{}, {"properties": {"r": "ome", "n": "uch a", "s": "some string"}}], + [{}, {"properties": {"r": "some string", "n": "other text", "s": "some string"}}], + [{}, {"properties": {"r": "ME", "n": "ch a", "s": "some string"}}], + [{}, {"properties": {"r": "string", "n": "text", "s": "some string"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "string" + }, + "outputs": [ + "such a string", + "other text", + "some string", + "some text" + ], + "serialized": ["regex-replace", ["get", "r"], ["get", "n"], ["get", "s"]] + } +} diff --git a/test/integration/expression-tests/regex-test/basic/test.json b/test/integration/expression-tests/regex-test/basic/test.json new file mode 100644 index 00000000000..f662532a9aa --- /dev/null +++ b/test/integration/expression-tests/regex-test/basic/test.json @@ -0,0 +1,24 @@ +{ + "expression": ["regex-test", ["get", "r"], ["get", "s"]], + "inputs": [ + [{}, {"properties": {"r": ".*", "s": "some string"}}], + [{}, {"properties": {"r": "(.*) string", "s": "some string"}}], + [{}, {"properties": {"r": "NO.*MATCH", "s": "some string"}}], + [{}, {"properties": {"r": "SOME string", "s": "some string"}}] + ], + "expected": { + "compiled": { + "result": "success", + "isFeatureConstant": false, + "isZoomConstant": true, + "type": "boolean" + }, + "outputs": [ + true, + true, + false, + false + ], + "serialized": ["regex-test", ["get", "r"], ["get", "s"]] + } +}