-
Notifications
You must be signed in to change notification settings - Fork 198
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
An implementation to have regex introduced into Winglang Motivation [first step to Add Regex type to String.replace() #3644 ] Solution I have implemented regex match function by using the match in Javascript. It takes in the userString and regexPattern string (example below) and returns a true if they match ; false otherwise. ``` let userString = "peach"; let regexPattern = "p[a-z]+h"; let matches = userString.match(regexPattern); assert(matches == true); ``` It returns a boolean value of true or false. ## Checklist - [ ] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted) - [ ] Description explains motivation and solution - [ ] Tests added (always) - [ ] Docs updated (only required for features) - [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing *By submitting this pull request, I confirm that my contribution is made under the terms of the [Wing Cloud Contribution License](https://github.com/winglang/wing/blob/main/CONTRIBUTION_LICENSE.md)*.
- Loading branch information
Showing
7 changed files
with
336 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
bring regex; | ||
|
||
let matches1 = regex.match("p[a-z]+ch" , "peach"); | ||
let matches2 = regex.match("[0-9]+" , "0923"); | ||
let matches3 = regex.match("[0-9]+" , "0a923"); | ||
let matches4 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$" , "[email protected]"); | ||
|
||
let matches5 = regex.match("p([a-z]+)ch" , "leach"); | ||
let matches6 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+" , "@[email protected]"); | ||
|
||
let matches7 = regex.match("^Mary" , "Mary had a little lamb"); | ||
let matches8 = regex.match("lamb\$" , "Mary had a little lamb"); | ||
|
||
let matches9 = regex.match("lamb\$" , "Mary had a little hamb"); | ||
let matches10 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$" , "[email protected]"); | ||
|
||
assert(matches1 == true ); | ||
assert(matches2 == true ); | ||
assert(matches3 == true ); | ||
assert(matches4 == true ); | ||
|
||
assert(matches5 == false); | ||
assert(matches6 == false); | ||
|
||
assert(matches7 == true ); | ||
assert(matches8 == true ); | ||
|
||
assert(matches9 == false); | ||
assert(matches10 == false); | ||
|
||
test "inflight match" { | ||
|
||
let matches1 = regex.match("p[a-z]+ch" , "peach"); | ||
let matches2 = regex.match("[0-9]+" , "0923"); | ||
let matches3 = regex.match("[0-9]+" , "0a923"); | ||
let matches4 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$" , "[email protected]"); | ||
|
||
let matches5 = regex.match("p([a-z]+)ch" , "leach"); | ||
let matches6 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+" , "@[email protected]"); | ||
|
||
let matches7 = regex.match("^Mary" , "Mary had a little lamb"); | ||
let matches8 = regex.match("lamb\$" , "Mary had a little lamb"); | ||
|
||
let matches9 = regex.match("lamb\$" , "Mary had a little hamb"); | ||
let matches10 = regex.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$" , "[email protected]"); | ||
|
||
|
||
assert(matches1 == true ); | ||
assert(matches2 == true ); | ||
assert(matches3 == true ); | ||
assert(matches4 == true ); | ||
|
||
assert(matches5 == false); | ||
assert(matches6 == false); | ||
|
||
assert(matches7 == true ); | ||
assert(matches8 == true ); | ||
|
||
assert(matches9 == false); | ||
assert(matches10 == false); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./regex"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import { InflightClient } from "../core"; | ||
|
||
/** | ||
* Regex utilities and functions | ||
*/ | ||
export class Util { | ||
/** | ||
* Check if a regex pattern is matched by a given string | ||
* @param pattern - regex pattern | ||
* @param text - given input string | ||
* @returns true if it matches the pattern, false otherwise | ||
*/ | ||
public static match(pattern: string, text: string): boolean { | ||
const regex = new RegExp(pattern); | ||
if (text.match(regex) === null) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
public static _toInflightType(): string { | ||
return InflightClient.forType(__filename, this.name); | ||
} | ||
private constructor() {} | ||
} |
229 changes: 229 additions & 0 deletions
229
tools/hangar/__snapshots__/test_corpus/sdk_tests/regex/match.w_compile_tf-aws.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,229 @@ | ||
# [match.w](../../../../../../examples/tests/sdk_tests/regex/match.w) | compile | tf-aws | ||
|
||
## inflight.$Closure1-1.js | ||
```js | ||
module.exports = function({ $regex_Util }) { | ||
class $Closure1 { | ||
constructor({ }) { | ||
const $obj = (...args) => this.handle(...args); | ||
Object.setPrototypeOf($obj, this); | ||
return $obj; | ||
} | ||
async handle() { | ||
const matches1 = (await $regex_Util.match("p[a-z]+ch","peach")); | ||
const matches2 = (await $regex_Util.match("[0-9]+","0923")); | ||
const matches3 = (await $regex_Util.match("[0-9]+","0a923")); | ||
const matches4 = (await $regex_Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$","[email protected]")); | ||
const matches5 = (await $regex_Util.match("p([a-z]+)ch","leach")); | ||
const matches6 = (await $regex_Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+","@[email protected]")); | ||
const matches7 = (await $regex_Util.match("^Mary","Mary had a little lamb")); | ||
const matches8 = (await $regex_Util.match("lamb\$","Mary had a little lamb")); | ||
const matches9 = (await $regex_Util.match("lamb\$","Mary had a little hamb")); | ||
const matches10 = (await $regex_Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$","[email protected]")); | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches1 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches1,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches2 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches2,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches3 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches3,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches4 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches4,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches5 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches5,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches6 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches6,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches7 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches7,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches8 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches8,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches9 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches9,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches10 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches10,false)))}; | ||
} | ||
} | ||
return $Closure1; | ||
} | ||
|
||
``` | ||
|
||
## main.tf.json | ||
```json | ||
{ | ||
"//": { | ||
"metadata": { | ||
"backend": "local", | ||
"stackName": "root", | ||
"version": "0.17.0" | ||
}, | ||
"outputs": { | ||
"root": { | ||
"Default": { | ||
"cloud.TestRunner": { | ||
"TestFunctionArns": "WING_TEST_RUNNER_FUNCTION_ARNS" | ||
} | ||
} | ||
} | ||
} | ||
}, | ||
"output": { | ||
"WING_TEST_RUNNER_FUNCTION_ARNS": { | ||
"value": "[[\"root/Default/Default/test:inflight match\",\"${aws_lambda_function.testinflightmatch_Handler_91AFEF4E.arn}\"]]" | ||
} | ||
}, | ||
"provider": { | ||
"aws": [ | ||
{} | ||
] | ||
}, | ||
"resource": { | ||
"aws_iam_role": { | ||
"testinflightmatch_Handler_IamRole_DA813D38": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Default/test:inflight match/Handler/IamRole", | ||
"uniqueId": "testinflightmatch_Handler_IamRole_DA813D38" | ||
} | ||
}, | ||
"assume_role_policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Action\":\"sts:AssumeRole\",\"Principal\":{\"Service\":\"lambda.amazonaws.com\"},\"Effect\":\"Allow\"}]}" | ||
} | ||
}, | ||
"aws_iam_role_policy": { | ||
"testinflightmatch_Handler_IamRolePolicy_B7F9EB14": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Default/test:inflight match/Handler/IamRolePolicy", | ||
"uniqueId": "testinflightmatch_Handler_IamRolePolicy_B7F9EB14" | ||
} | ||
}, | ||
"policy": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Action\":\"none:null\",\"Resource\":\"*\"}]}", | ||
"role": "${aws_iam_role.testinflightmatch_Handler_IamRole_DA813D38.name}" | ||
} | ||
}, | ||
"aws_iam_role_policy_attachment": { | ||
"testinflightmatch_Handler_IamRolePolicyAttachment_B8D01B6A": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Default/test:inflight match/Handler/IamRolePolicyAttachment", | ||
"uniqueId": "testinflightmatch_Handler_IamRolePolicyAttachment_B8D01B6A" | ||
} | ||
}, | ||
"policy_arn": "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole", | ||
"role": "${aws_iam_role.testinflightmatch_Handler_IamRole_DA813D38.name}" | ||
} | ||
}, | ||
"aws_lambda_function": { | ||
"testinflightmatch_Handler_91AFEF4E": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Default/test:inflight match/Handler/Default", | ||
"uniqueId": "testinflightmatch_Handler_91AFEF4E" | ||
} | ||
}, | ||
"architectures": [ | ||
"arm64" | ||
], | ||
"environment": { | ||
"variables": { | ||
"WING_FUNCTION_NAME": "Handler-c8aa61ca", | ||
"WING_TARGET": "tf-aws" | ||
} | ||
}, | ||
"function_name": "Handler-c8aa61ca", | ||
"handler": "index.handler", | ||
"publish": true, | ||
"role": "${aws_iam_role.testinflightmatch_Handler_IamRole_DA813D38.arn}", | ||
"runtime": "nodejs18.x", | ||
"s3_bucket": "${aws_s3_bucket.Code.bucket}", | ||
"s3_key": "${aws_s3_object.testinflightmatch_Handler_S3Object_2184865C.key}", | ||
"timeout": 30, | ||
"vpc_config": { | ||
"security_group_ids": [], | ||
"subnet_ids": [] | ||
} | ||
} | ||
}, | ||
"aws_s3_bucket": { | ||
"Code": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Code", | ||
"uniqueId": "Code" | ||
} | ||
}, | ||
"bucket_prefix": "code-c84a50b1-" | ||
} | ||
}, | ||
"aws_s3_object": { | ||
"testinflightmatch_Handler_S3Object_2184865C": { | ||
"//": { | ||
"metadata": { | ||
"path": "root/Default/Default/test:inflight match/Handler/S3Object", | ||
"uniqueId": "testinflightmatch_Handler_S3Object_2184865C" | ||
} | ||
}, | ||
"bucket": "${aws_s3_bucket.Code.bucket}", | ||
"key": "<ASSET_KEY>", | ||
"source": "<ASSET_SOURCE>" | ||
} | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## preflight.js | ||
```js | ||
const $stdlib = require('@winglang/sdk'); | ||
const $plugins = ((s) => !s ? [] : s.split(';'))(process.env.WING_PLUGIN_PATHS); | ||
const $outdir = process.env.WING_SYNTH_DIR ?? "."; | ||
const $wing_is_test = process.env.WING_IS_TEST === "true"; | ||
const std = $stdlib.std; | ||
const regex = $stdlib.regex; | ||
class $Root extends $stdlib.std.Resource { | ||
constructor(scope, id) { | ||
super(scope, id); | ||
class $Closure1 extends $stdlib.std.Resource { | ||
constructor(scope, id, ) { | ||
super(scope, id); | ||
(std.Node.of(this)).hidden = true; | ||
} | ||
static _toInflightType(context) { | ||
return ` | ||
require("./inflight.$Closure1-1.js")({ | ||
$regex_Util: ${context._lift(regex.Util)}, | ||
}) | ||
`; | ||
} | ||
_toInflight() { | ||
return ` | ||
(await (async () => { | ||
const $Closure1Client = ${$Closure1._toInflightType(this)}; | ||
const client = new $Closure1Client({ | ||
}); | ||
if (client.$inflight_init) { await client.$inflight_init(); } | ||
return client; | ||
})()) | ||
`; | ||
} | ||
_getInflightOps() { | ||
return ["handle", "$inflight_init"]; | ||
} | ||
} | ||
const matches1 = (regex.Util.match("p[a-z]+ch","peach")); | ||
const matches2 = (regex.Util.match("[0-9]+","0923")); | ||
const matches3 = (regex.Util.match("[0-9]+","0a923")); | ||
const matches4 = (regex.Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$","[email protected]")); | ||
const matches5 = (regex.Util.match("p([a-z]+)ch","leach")); | ||
const matches6 = (regex.Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+","@[email protected]")); | ||
const matches7 = (regex.Util.match("^Mary","Mary had a little lamb")); | ||
const matches8 = (regex.Util.match("lamb\$","Mary had a little lamb")); | ||
const matches9 = (regex.Util.match("lamb\$","Mary had a little hamb")); | ||
const matches10 = (regex.Util.match("^([a-zA-Z0-9_.-]+)@[a-z]+.[a-z]+\$","[email protected]")); | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches1 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches1,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches2 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches2,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches3 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches3,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches4 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches4,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches5 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches5,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches6 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches6,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches7 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches7,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches8 == true ")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches8,true)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches9 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches9,false)))}; | ||
{((cond) => {if (!cond) throw new Error("assertion failed: matches10 == false")})((((a,b) => { try { return require('assert').deepStrictEqual(a,b) === undefined; } catch { return false; } })(matches10,false)))}; | ||
this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:inflight match",new $Closure1(this,"$Closure1")); | ||
} | ||
} | ||
const $App = $stdlib.core.App.for(process.env.WING_TARGET); | ||
new $App({ outdir: $outdir, name: "match", rootConstruct: $Root, plugins: $plugins, isTestEnvironment: $wing_is_test, entrypointDir: process.env['WING_SOURCE_DIR'], rootId: process.env['WING_ROOT_ID'] }).synth(); | ||
|
||
``` | ||
12 changes: 12 additions & 0 deletions
12
tools/hangar/__snapshots__/test_corpus/sdk_tests/regex/match.w_test_sim.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# [match.w](../../../../../../examples/tests/sdk_tests/regex/match.w) | test | sim | ||
|
||
## stdout.log | ||
```log | ||
pass ─ match.wsim » root/env0/test:inflight match | ||
Tests 1 passed (1) | ||
Test Files 1 passed (1) | ||
Duration <DURATION> | ||
``` | ||
|