summaryrefslogtreecommitdiffstats
path: root/modules/regex
diff options
context:
space:
mode:
Diffstat (limited to 'modules/regex')
-rw-r--r--modules/regex/doc_classes/RegEx.xml2
-rw-r--r--modules/regex/icons/RegEx.svg1
-rw-r--r--modules/regex/icons/RegExMatch.svg1
-rw-r--r--modules/regex/tests/test_regex.h80
4 files changed, 79 insertions, 5 deletions
diff --git a/modules/regex/doc_classes/RegEx.xml b/modules/regex/doc_classes/RegEx.xml
index 5770e7155e..ab74fce3a9 100644
--- a/modules/regex/doc_classes/RegEx.xml
+++ b/modules/regex/doc_classes/RegEx.xml
@@ -10,7 +10,7 @@
var regex = RegEx.new()
regex.compile("\\w-(\\d+)")
[/codeblock]
- The search pattern must be escaped first for GDScript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code].
+ The search pattern must be escaped first for GDScript before it is escaped for the expression. For example, [code]compile("\\d+")[/code] would be read by RegEx as [code]\d+[/code]. Similarly, [code]compile("\"(?:\\\\.|[^\"])*\"")[/code] would be read as [code]"(?:\\.|[^"])*"[/code]. In GDScript, you can also use raw string literals (r-strings). For example, [code]compile(r'"(?:\\.|[^"])*"')[/code] would be read the same.
Using [method search], you can find the pattern within the given text. If a pattern is found, [RegExMatch] is returned and you can retrieve details of the results using methods such as [method RegExMatch.get_string] and [method RegExMatch.get_start].
[codeblock]
var regex = RegEx.new()
diff --git a/modules/regex/icons/RegEx.svg b/modules/regex/icons/RegEx.svg
new file mode 100644
index 0000000000..4df26f41c0
--- /dev/null
+++ b/modules/regex/icons/RegEx.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M2 14h3v-3H2zM6.561 2.855a21 21 0 0 1 2.82 1.185A21 21 0 0 1 9.137 1h1.77a21 21 0 0 1-.28 3.027 21 21 0 0 1 2.88-1.171l.562 1.733a21 21 0 0 1-3.04.684 21 21 0 0 1 2.1 2.307l-1.465 1.037a21 21 0 0 1-1.672-2.624 21 21 0 0 1-1.587 2.624L6.965 7.58a21 21 0 0 1 2.026-2.308A21 21 0 0 1 6 4.59z" fill="#e0e0e0"/></svg>
diff --git a/modules/regex/icons/RegExMatch.svg b/modules/regex/icons/RegExMatch.svg
new file mode 100644
index 0000000000..889cf6cc8a
--- /dev/null
+++ b/modules/regex/icons/RegExMatch.svg
@@ -0,0 +1 @@
+<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="M5 13h2v-2H5zm2.5-8a14 14 0 0 1 1.88.79 14 14 0 0 1-.163-2.027h1.18a14 14 0 0 1-.186 2.018 14 14 0 0 1 1.92-.78l.374 1.155a14 14 0 0 1-2.026.456 14 14 0 0 1 1.4 1.538l-.977.691a14 14 0 0 1-1.115-1.75 14 14 0 0 1-1.058 1.75l-.96-.691A14 14 0 0 1 9.12 6.61a14 14 0 0 1-1.993-.454zM1.67 2C0 5 0 11 1.67 14h2C2 11 2 5 3.67 2zm10.66 0c1.67 3 1.67 9 0 12h2c1.67-3 1.67-9 0-12z" fill="#e0e0e0"/></svg>
diff --git a/modules/regex/tests/test_regex.h b/modules/regex/tests/test_regex.h
index 6515d5d130..3e4d769377 100644
--- a/modules/regex/tests/test_regex.h
+++ b/modules/regex/tests/test_regex.h
@@ -83,9 +83,16 @@ TEST_CASE("[RegEx] Searching") {
REQUIRE(match != nullptr);
CHECK(match->get_string(0) == "ea");
+ match = re.search(s, 1, 2);
+ REQUIRE(match != nullptr);
+ CHECK(match->get_string(0) == "e");
match = re.search(s, 2, 4);
REQUIRE(match != nullptr);
CHECK(match->get_string(0) == "a");
+ match = re.search(s, 3, 5);
+ CHECK(match == nullptr);
+ match = re.search(s, 6, 2);
+ CHECK(match == nullptr);
const Array all_results = re.search_all(s);
CHECK(all_results.size() == 2);
@@ -103,11 +110,45 @@ TEST_CASE("[RegEx] Searching") {
}
TEST_CASE("[RegEx] Substitution") {
- String s = "Double all the vowels.";
+ const String s1 = "Double all the vowels.";
- RegEx re("(?<vowel>[aeiou])");
- REQUIRE(re.is_valid());
- CHECK(re.sub(s, "$0$vowel", true) == "Doouublee aall thee vooweels.");
+ RegEx re1("(?<vowel>[aeiou])");
+ REQUIRE(re1.is_valid());
+ CHECK(re1.sub(s1, "$0$vowel", true) == "Doouublee aall thee vooweels.");
+
+ const String s2 = "Substitution with group.";
+
+ RegEx re2("Substitution (.+)");
+ REQUIRE(re2.is_valid());
+ CHECK(re2.sub(s2, "Test ${1}") == "Test with group.");
+
+ const String s3 = "Useless substitution";
+
+ RegEx re3("Anything");
+ REQUIRE(re3.is_valid());
+ CHECK(re3.sub(s3, "Something") == "Useless substitution");
+
+ const String s4 = "acacac";
+
+ RegEx re4("(a)(b){0}(c)");
+ REQUIRE(re4.is_valid());
+ CHECK(re4.sub(s4, "${1}.${3}.", true) == "a.c.a.c.a.c.");
+}
+
+TEST_CASE("[RegEx] Substitution with empty input and/or replacement") {
+ const String s1 = "";
+ const String s2 = "gogogo";
+
+ RegEx re1("");
+ REQUIRE(re1.is_valid());
+ CHECK(re1.sub(s1, "") == "");
+ CHECK(re1.sub(s1, "a") == "a");
+ CHECK(re1.sub(s2, "") == "gogogo");
+
+ RegEx re2("go");
+ REQUIRE(re2.is_valid());
+ CHECK(re2.sub(s2, "") == "gogo");
+ CHECK(re2.sub(s2, "", true) == "");
}
TEST_CASE("[RegEx] Uninitialized use") {
@@ -150,6 +191,37 @@ TEST_CASE("[RegEx] Invalid end position") {
CHECK(re.sub(s, "", true, 0, 10) == "Gdt");
}
+
+TEST_CASE("[RegEx] Get match string list") {
+ const String s = "Godot Engine";
+
+ RegEx re("(Go)(dot)");
+ Ref<RegExMatch> match = re.search(s);
+ REQUIRE(match != nullptr);
+ PackedStringArray result;
+ result.append("Godot");
+ result.append("Go");
+ result.append("dot");
+ CHECK(match->get_strings() == result);
+}
+
+TEST_CASE("[RegEx] Match start and end positions") {
+ const String s = "Whole pattern";
+
+ RegEx re1("pattern");
+ REQUIRE(re1.is_valid());
+ Ref<RegExMatch> match = re1.search(s);
+ REQUIRE(match != nullptr);
+ CHECK(match->get_start(0) == 6);
+ CHECK(match->get_end(0) == 13);
+
+ RegEx re2("(?<vowel>[aeiou])");
+ REQUIRE(re2.is_valid());
+ match = re2.search(s);
+ REQUIRE(match != nullptr);
+ CHECK(match->get_start("vowel") == 2);
+ CHECK(match->get_end("vowel") == 3);
+}
} // namespace TestRegEx
#endif // TEST_REGEX_H