aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLouis Pilfold <louis@lpil.uk>2021-08-26 19:03:00 +0100
committerLouis Pilfold <louis@lpil.uk>2021-08-27 00:37:15 +0100
commit794f0740fa98a218bb210da1d96f39409e5907c6 (patch)
treec4869a3d7f0613e33c8d14e840bcf0cc0fb17cb1
parent0d6bf1f289cc6cb247afff8c5f2cdc2277ac94c6 (diff)
downloadgleam_stdlib-794f0740fa98a218bb210da1d96f39409e5907c6.tar.gz
gleam_stdlib-794f0740fa98a218bb210da1d96f39409e5907c6.zip
Regex compile
-rw-r--r--bin/run-tests.js2
-rw-r--r--src/gleam/regex.gleam181
-rw-r--r--src/gleam_stdlib.erl2
-rw-r--r--test/gleam/regex_test.gleam27
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.?")