Browse Source

Added third argument for String.split() function (see issue #14349)

Remove negative limit, leave only positive and make it reflect behaviour like in Python
Also limit renamed to maxsplit to match Python one.
Also docs updated.

Fix indent
Dmitry Koteroff 7 years ago
parent
commit
5302fd125b
4 changed files with 22 additions and 6 deletions
  1. 16 3
      core/ustring.cpp
  2. 1 1
      core/ustring.h
  3. 2 2
      core/variant_call.cpp
  4. 3 0
      doc/classes/String.xml

+ 16 - 3
core/ustring.cpp

@@ -734,7 +734,7 @@ Vector<String> String::split_spaces() const {
 	return ret;
 }
 
-Vector<String> String::split(const String &p_splitter, bool p_allow_empty) const {
+Vector<String> String::split(const String &p_splitter, bool p_allow_empty, int p_maxsplit) const {
 
 	Vector<String> ret;
 	int from = 0;
@@ -745,8 +745,21 @@ Vector<String> String::split(const String &p_splitter, bool p_allow_empty) const
 		int end = find(p_splitter, from);
 		if (end < 0)
 			end = len;
-		if (p_allow_empty || (end > from))
-			ret.push_back(substr(from, end - from));
+		if (p_allow_empty || (end > from)) {
+			if (p_maxsplit <= 0)
+				ret.push_back(substr(from, end - from));
+			else if (p_maxsplit > 0) {
+
+				// Put rest of the string and leave cycle.
+				if (p_maxsplit == ret.size()) {
+					ret.push_back(substr(from, len));
+					break;
+				}
+
+				// Otherwise, push items until positive limit is reached.
+				ret.push_back(substr(from, end - from));
+			}
+		}
 
 		if (end == len)
 			break;

+ 1 - 1
core/ustring.h

@@ -162,7 +162,7 @@ public:
 	String get_slice(String p_splitter, int p_slice) const;
 	String get_slicec(CharType p_splitter, int p_slice) const;
 
-	Vector<String> split(const String &p_splitter, bool p_allow_empty = true) const;
+	Vector<String> split(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 - 2
core/variant_call.cpp

@@ -254,7 +254,7 @@ struct _VariantCall {
 	VCALL_LOCALMEM2R(String, replacen);
 	VCALL_LOCALMEM2R(String, insert);
 	VCALL_LOCALMEM0R(String, capitalize);
-	VCALL_LOCALMEM2R(String, split);
+	VCALL_LOCALMEM3R(String, split);
 	VCALL_LOCALMEM2R(String, split_floats);
 	VCALL_LOCALMEM0R(String, to_upper);
 	VCALL_LOCALMEM0R(String, to_lower);
@@ -1446,7 +1446,7 @@ void register_variant_methods() {
 	ADDFUNC2R(STRING, STRING, String, replacen, STRING, "what", STRING, "forwhat", varray());
 	ADDFUNC2R(STRING, STRING, String, insert, INT, "position", STRING, "what", varray());
 	ADDFUNC0R(STRING, STRING, String, capitalize, varray());
-	ADDFUNC2R(STRING, POOL_STRING_ARRAY, String, split, STRING, "divisor", BOOL, "allow_empty", varray(true));
+	ADDFUNC3R(STRING, POOL_STRING_ARRAY, String, split, 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());

+ 3 - 0
doc/classes/String.xml

@@ -662,8 +662,11 @@
 			</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 divisor string and returns an array of the substrings. Example "One,Two,Three" will return ["One","Two","Three"] if split by ",".
+				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="split_floats">