From 6fe415ca7f439d56321d327dfdd18105a09a70d1 Mon Sep 17 00:00:00 2001 From: Dmitry Koteroff Date: Fri, 15 Dec 2017 22:23:58 +0300 Subject: [PATCH] Added rsplit() for String class Docs updated --- core/ustring.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ core/ustring.h | 1 + core/variant_call.cpp | 2 ++ doc/classes/String.xml | 14 ++++++++++++++ 4 files changed, 57 insertions(+) diff --git a/core/ustring.cpp b/core/ustring.cpp index 1bf7d000c3..621fdf4011 100644 --- a/core/ustring.cpp +++ b/core/ustring.cpp @@ -770,6 +770,46 @@ Vector String::split(const String &p_splitter, bool p_allow_empty, int p return ret; } +Vector String::rsplit(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const { + + Vector ret; + const int len = length(); + int from = len; + + while (true) { + + int end = rfind(p_splitter, from); + if (end < 0) + end = 0; + + if (p_allow_empty || (end < from)) { + const String str = substr(end > 0 ? end + p_splitter.length() : end, end > 0 ? from - end : from + 2); + + if (p_maxsplit <= 0) { + ret.push_back(str); + } else if (p_maxsplit > 0) { + + // Put rest of the string and leave cycle. + if (p_maxsplit == ret.size()) { + ret.push_back(substr(0, from + 2)); + break; + } + + // Otherwise, push items until positive limit is reached. + ret.push_back(str); + } + } + + if (end == 0) + break; + + from = end - p_splitter.length(); + } + + ret.invert(); + return ret; +} + Vector String::split_floats(const String &p_splitter, bool p_allow_empty) const { Vector ret; diff --git a/core/ustring.h b/core/ustring.h index 6541642bd1..c0cf5042e0 100644 --- a/core/ustring.h +++ b/core/ustring.h @@ -163,6 +163,7 @@ public: String get_slicec(CharType p_splitter, int p_slice) const; Vector split(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const; + Vector rsplit(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const; Vector split_spaces() const; Vector split_floats(const String &p_splitter, bool p_allow_empty = true) const; Vector split_floats_mk(const Vector &p_splitters, bool p_allow_empty = true) const; diff --git a/core/variant_call.cpp b/core/variant_call.cpp index 2b99a60ba5..4cc29b2588 100644 --- a/core/variant_call.cpp +++ b/core/variant_call.cpp @@ -255,6 +255,7 @@ struct _VariantCall { VCALL_LOCALMEM2R(String, insert); VCALL_LOCALMEM0R(String, capitalize); VCALL_LOCALMEM3R(String, split); + VCALL_LOCALMEM3R(String, rsplit); VCALL_LOCALMEM2R(String, split_floats); VCALL_LOCALMEM0R(String, to_upper); VCALL_LOCALMEM0R(String, to_lower); @@ -1447,6 +1448,7 @@ void register_variant_methods() { ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray()); ADDFUNC0R(STRING, STRING, String, capitalize, varray()); ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); + ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, rsplit, STRING, "divisor", BOOL, "allow_empty", INT, "maxsplit", varray(true, 0)); ADDFUNC2R(STRING, POOL_REAL_ARRAY, String, split_floats, STRING, "divisor", BOOL, "allow_empty", varray(true)); ADDFUNC0R(STRING, STRING, String, to_upper, varray()); diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 8bbd52b417..9240009d9b 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -669,6 +669,20 @@ If [code]maxsplit[/code] is given, at most maxsplit number of splits occur, and the remainder of the string is returned as the final element of the list (thus, the list will have at most maxsplit+1 elements) + + + + + + + + + + + Splits the string by a [code]divisor[/code] string and returns an array of the substrings, starting from right. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",". + If [code]maxsplit[/code] is specified, then it is number of splits to do, default is 0 which splits all the items. + +