Explorar el Código

Merge pull request #14715 from Krakean/string_add_rsplit2

Added rsplit() method to String class
Max Hilbrunner hace 7 años
padre
commit
acf6c326fb
Se han modificado 4 ficheros con 57 adiciones y 0 borrados
  1. 40 0
      core/ustring.cpp
  2. 1 0
      core/ustring.h
  3. 2 0
      core/variant_call.cpp
  4. 14 0
      doc/classes/String.xml

+ 40 - 0
core/ustring.cpp

@@ -753,6 +753,46 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p
 	return ret;
 }
 
+Vector<String> String::rsplit(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
+
+	Vector<String> 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<float> String::split_floats(const String &p_splitter, bool p_allow_empty) const {
 
 	Vector<float> ret;

+ 1 - 0
core/ustring.h

@@ -172,6 +172,7 @@ public:
 	String get_slicec(CharType p_splitter, int p_slice) const;
 
 	Vector<String> split(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
+	Vector<String> rsplit(const String &p_splitter, bool p_allow_empty = true, int p_maxsplit = 0) const;
 	Vector<String> split_spaces() const;
 	Vector<float> split_floats(const String &p_splitter, bool p_allow_empty = true) const;
 	Vector<float> split_floats_mk(const Vector<String> &p_splitters, bool p_allow_empty = true) const;

+ 2 - 0
core/variant_call.cpp

@@ -257,6 +257,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);
@@ -1469,6 +1470,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());

+ 14 - 0
doc/classes/String.xml

@@ -688,6 +688,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)
 			</description>
 		</method>
+		<method name="rsplit">
+			<return type="PoolStringArray">
+			</return>
+			<argument index="0" name="divisor" type="String">
+			</argument>
+			<argument index="1" name="allow_empty" type="bool" default="True">
+			</argument>
+			<argument index="2" name="maxsplit" type="int" default="0">
+			</argument>
+			<description>
+				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.
+			</description>
+		</method>
 		<method name="split_floats">
 			<return type="PoolRealArray">
 			</return>