diff options
author | Louis Pilfold <louis@lpil.uk> | 2021-08-26 19:03:00 +0100 |
---|---|---|
committer | Louis Pilfold <louis@lpil.uk> | 2021-08-27 00:37:15 +0100 |
commit | 794f0740fa98a218bb210da1d96f39409e5907c6 (patch) | |
tree | c4869a3d7f0613e33c8d14e840bcf0cc0fb17cb1 | |
parent | 0d6bf1f289cc6cb247afff8c5f2cdc2277ac94c6 (diff) | |
download | gleam_stdlib-794f0740fa98a218bb210da1d96f39409e5907c6.tar.gz gleam_stdlib-794f0740fa98a218bb210da1d96f39409e5907c6.zip |
Regex compile
-rw-r--r-- | bin/run-tests.js | 2 | ||||
-rw-r--r-- | src/gleam/regex.gleam | 181 | ||||
-rw-r--r-- | src/gleam_stdlib.erl | 2 | ||||
-rw-r--r-- | test/gleam/regex_test.gleam | 27 |
4 files changed, 120 insertions, 92 deletions
diff --git a/bin/run-tests.js b/bin/run-tests.js index bd5475f..3eaba7c 100644 --- a/bin/run-tests.js +++ b/bin/run-tests.js @@ -17,7 +17,7 @@ async function main() { if (!fnName.endsWith("_test")) continue; try { module[fnName](); - process.stdout.write(`\u001b[${32}m.\u001b[${0}m`); + process.stdout.write(`\u001b[32m.\u001b[0m`); passes++; } catch (error) { let moduleName = "\ngleam/" + entry.name.slice(0, -3); diff --git a/src/gleam/regex.gleam b/src/gleam/regex.gleam index 87f06c8..e59d049 100644 --- a/src/gleam/regex.gleam +++ b/src/gleam/regex.gleam @@ -3,93 +3,118 @@ //// all of the PCRE library is interfaced and some parts of the library go beyond //// what PCRE offers. Currently PCRE version 8.40 (release date 2017-01-11) is used. -if erlang { - import gleam/option.{Option} +import gleam/option.{Option} - pub external type Regex +pub external type Regex - /// The details about a particular match: - /// - pub type Match { - Match( - /// The full string of the match. - content: String, - /// The byte index of the match in the original string. - byte_index: Int, - /// A Regex can have subpatterns, sup-parts that are in parentheses. - submatches: List(Option(String)), - ) - } +/// The details about a particular match: +/// +pub type Match { + Match( + /// The full string of the match. + content: String, + /// The byte index of the match in the original string. + byte_index: Int, + /// A Regex can have subpatterns, sup-parts that are in parentheses. + submatches: List(Option(String)), + ) +} - /// When a regular expression fails to compile: - /// - pub type CompileError { - CompileError( - /// The problem encountered that caused the compilation to fail - error: String, - /// The byte index into the string to where the problem was found - byte_index: Int, - ) - } +/// When a regular expression fails to compile: +/// +pub type CompileError { + CompileError( + /// The problem encountered that caused the compilation to fail + error: String, + /// The byte index into the string to where the problem was found + byte_index: Int, + ) +} - pub type Options { - Options(case_insensitive: Bool, multi_line: Bool) - } +pub type Options { + Options(case_insensitive: Bool, multi_line: Bool) +} - /// Creates a Regex with some additional options. - /// - /// ## Examples - /// - /// > let options = Options(case_insensitive: False, multi_line: True) - /// > assert Ok(re) = compile("^[0-9]", with: options) - /// > match(re, "abc\n123") - /// True - /// - /// > let options = Options(case_insensitive: True, multi_line: False) - /// > assert Ok(re) = compile("[A-Z]", with: options) - /// > match(re, "abc123") - /// True - /// - pub external fn compile(String, with: Options) -> Result(Regex, CompileError) = +/// Creates a Regex with some additional options. +/// +/// ## Examples +/// +/// > let options = Options(case_insensitive: False, multi_line: True) +/// > assert Ok(re) = compile("^[0-9]", with: options) +/// > match(re, "abc\n123") +/// True +/// +/// > let options = Options(case_insensitive: True, multi_line: False) +/// > assert Ok(re) = compile("[A-Z]", with: options) +/// > match(re, "abc123") +/// True +/// +pub fn compile( + pattern: String, + with options: Options, +) -> Result(Regex, CompileError) { + do_compile(pattern, options) +} + +if erlang { + external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = "gleam_stdlib" "compile_regex" +} - /// Creates a new Regex. - /// - /// ## Examples - /// - /// > assert Ok(re) = from_string("[0-9]") - /// > match(re, "abc123") - /// True - /// - /// > match(re, "abcxyz") - /// False - /// - /// > from_string("[0-9") - /// Error( - /// CompileError( - /// error: "missing terminating ] for character class", - /// byte_index: 4 - /// ) - /// ) - /// - pub fn from_string(pattern: String) -> Result(Regex, CompileError) { - compile(pattern, Options(case_insensitive: False, multi_line: False)) - } +if javascript { + external fn do_compile(String, with: Options) -> Result(Regex, CompileError) = + "../gleam_stdlib.js" "compile_regex" +} - /// Returns a boolean indicating whether there was a match or not. - /// - /// ## Examples - /// - /// > assert Ok(re) = from_string("^f.o.?") - /// > check(with: re, content: "foo") - /// True - /// - /// > check(with: re, content: "boo") - /// False - /// - pub external fn check(with: Regex, content: String) -> Bool = - "gleam_stdlib" "regex_match" +/// Creates a new Regex. +/// +/// ## Examples +/// +/// > assert Ok(re) = from_string("[0-9]") +/// > match(re, "abc123") +/// True +/// +/// > match(re, "abcxyz") +/// False +/// +/// > from_string("[0-9") +/// Error( +/// CompileError( +/// error: "missing terminating ] for character class", +/// byte_index: 4 +/// ) +/// ) +/// +pub fn from_string(pattern: String) -> Result(Regex, CompileError) { + compile(pattern, Options(case_insensitive: False, multi_line: False)) +} + +/// Returns a boolean indicating whether there was a match or not. +/// +/// ## Examples +/// +/// > assert Ok(re) = from_string("^f.o.?") +/// > check(with: re, content: "foo") +/// True +/// +/// > check(with: re, content: "boo") +/// False +/// +pub fn check(with regex: Regex, content content: String) -> Bool { + do_check(regex, content) +} +if erlang { + external fn do_check(Regex, String) -> Bool = + "gleam_stdlib" "regex_check" +} + +if javascript { + external fn do_check(Regex, String) -> Bool = + "../gleam_stdlib.js" "regex_check" +} + +if erlang { /// Splits a string /// /// ## Examples diff --git a/src/gleam_stdlib.erl b/src/gleam_stdlib.erl index d960a4f..fdb116b 100644 --- a/src/gleam_stdlib.erl +++ b/src/gleam_stdlib.erl @@ -204,7 +204,7 @@ compile_regex(String, Options) -> {error, {compile_error, unicode:characters_to_binary(Str), Pos}} end. -regex_match(Regex, String) -> +regex_check(Regex, String) -> re:run(String, Regex) /= nomatch. regex_split(Regex, String) -> diff --git a/test/gleam/regex_test.gleam b/test/gleam/regex_test.gleam index f6410e4..91d43c6 100644 --- a/test/gleam/regex_test.gleam +++ b/test/gleam/regex_test.gleam @@ -1,8 +1,9 @@ +import gleam/regex.{CompileError, Match, Options} +import gleam/should + if erlang { import gleam/io import gleam/option.{None, Some} - import gleam/regex.{CompileError, Match, Options} - import gleam/should pub fn from_string_test() { assert Ok(re) = regex.from_string("[0-9]") @@ -21,21 +22,23 @@ if erlang { byte_index: 4, )) } +} - pub fn compile_test() { - let options = Options(case_insensitive: True, multi_line: False) - assert Ok(re) = regex.compile("[A-B]", options) +pub fn compile_test() { + let options = Options(case_insensitive: True, multi_line: False) + assert Ok(re) = regex.compile("[A-B]", options) - regex.check(re, "abc123") - |> should.equal(True) + regex.check(re, "abc123") + |> should.equal(True) - let options = Options(case_insensitive: False, multi_line: True) - assert Ok(re) = regex.compile("^[0-9]", options) + let options = Options(case_insensitive: False, multi_line: True) + assert Ok(re) = regex.compile("^[0-9]", options) - regex.check(re, "abc\n123") - |> should.equal(True) - } + regex.check(re, "abc\n123") + |> should.equal(True) +} +if erlang { pub fn check_test() { assert Ok(re) = regex.from_string("^f.o.?") |