diff --git a/docs/source/config_reference/scripting/scripting_functions.rst b/docs/source/config_reference/scripting/scripting_functions.rst index db773b17e..d5948fb52 100644 --- a/docs/source/config_reference/scripting/scripting_functions.rst +++ b/docs/source/config_reference/scripting/scripting_functions.rst @@ -560,6 +560,15 @@ regex_search the string as the first element of the Array. If there are capture groups, returns each group as a subsequent element in the Array. +regex_sub +~~~~~~~~~ +:spec: ``regex_sub(regex: String, replacement: String, string: String) -> String`` + +:description: + Returns the string obtained by replacing the leftmost non-overlapping occurrences of the + pattern in string by the replacement string. The replacement string can reference the + match groups via backslash escapes. Callables as replacement argument are not supported. + ---------------------------------------------------------------------------------------------------- String Functions diff --git a/src/ytdl_sub/script/functions/regex_functions.py b/src/ytdl_sub/script/functions/regex_functions.py index f837be32b..feb204cea 100644 --- a/src/ytdl_sub/script/functions/regex_functions.py +++ b/src/ytdl_sub/script/functions/regex_functions.py @@ -52,3 +52,13 @@ def regex_capture_groups(regex: String) -> Integer: Returns number of capture groups in regex """ return Integer(re.compile(regex.value).groups) + + @staticmethod + def regex_sub(regex: String, replacement: String, string: String) -> String: + """ + :description: + Returns the string obtained by replacing the leftmost non-overlapping occurrences of the + pattern in string by the replacement string. The replacement string can reference the + match groups via backslash escapes. Callables as replacement argument are not supported. + """ + return String(re.sub(regex.value, replacement.value, string.value)) diff --git a/tests/unit/script/functions/test_regex_functions.py b/tests/unit/script/functions/test_regex_functions.py index b0ca2e167..3322134da 100644 --- a/tests/unit/script/functions/test_regex_functions.py +++ b/tests/unit/script/functions/test_regex_functions.py @@ -43,3 +43,19 @@ def test_regex_search(self, values: str, expected_output: str): def test_regex_fullmatch(self, values: str, expected_output: str): output = single_variable_output(f"{{%regex_fullmatch({values})}}") assert output == expected_output + + @pytest.mark.parametrize( + "values, expected_output", + [ + ("'[^A-Za-z0-9 ]', '', 'This title is AWESOME!!'", "This title is AWESOME"), + ("'\s+', '_', 'Consolidate spaces'", "Consolidate_spaces"), + ( + "'(words) are (reordered)', '\\2 are \\1', 'Oh words are reordered'", + "Oh reordered are words", + ), + ("'MATCH', '', 'matcha is great'", "matcha is great"), + ], + ) + def test_regex_sub(self, values: str, expected_output: str): + output = single_variable_output(f"{{%regex_sub({values})}}") + assert output == expected_output