diff --git a/core/config/project_settings.cpp b/core/config/project_settings.cpp index a9673cf79b3..75dfdaaa136 100644 --- a/core/config/project_settings.cpp +++ b/core/config/project_settings.cpp @@ -280,7 +280,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { if (p_value.get_type() == Variant::NIL) { props.erase(p_name); if (p_name.operator String().begins_with("autoload/")) { - String node_name = p_name.operator String().split("/")[1]; + String node_name = p_name.operator String().get_slicec('/', 1); if (autoloads.has(node_name)) { remove_autoload(node_name); } @@ -326,7 +326,7 @@ bool ProjectSettings::_set(const StringName &p_name, const Variant &p_value) { props[p_name] = VariantContainer(p_value, last_order++); } if (p_name.operator String().begins_with("autoload/")) { - String node_name = p_name.operator String().split("/")[1]; + String node_name = p_name.operator String().get_slicec('/', 1); AutoloadInfo autoload; autoload.name = node_name; String path = p_value; diff --git a/core/input/input.cpp b/core/input/input.cpp index 51f2c7f971f..e521bf16a76 100644 --- a/core/input/input.cpp +++ b/core/input/input.cpp @@ -1756,8 +1756,7 @@ void Input::parse_mapping(const String &p_mapping) { void Input::add_joy_mapping(const String &p_mapping, bool p_update_existing) { parse_mapping(p_mapping); if (p_update_existing) { - Vector entry = p_mapping.split(","); - const String &uid = entry[0]; + const String uid = p_mapping.get_slicec(',', 0); for (KeyValue &E : joy_names) { Joypad &joy = E.value; if (joy.uid == uid) { diff --git a/core/input/input_map.cpp b/core/input/input_map.cpp index 8e5fe25de2a..f310311ea11 100644 --- a/core/input/input_map.cpp +++ b/core/input/input_map.cpp @@ -843,9 +843,8 @@ const HashMap>> &InputMap::get_builtins_with_featur for (const KeyValue>> &E : builtins) { String fullname = E.key; - Vector split = fullname.split("."); - const String &name = split[0]; - String override_for = split.size() > 1 ? split[1] : String(); + const String &name = fullname.get_slicec('.', 0); + String override_for = fullname.get_slice_count(".") > 1 ? fullname.get_slicec('.', 1) : String(); if (!override_for.is_empty() && OS::get_singleton()->has_feature(override_for)) { builtins_with_overrides[name].push_back(override_for); @@ -855,9 +854,8 @@ const HashMap>> &InputMap::get_builtins_with_featur for (const KeyValue>> &E : builtins) { String fullname = E.key; - Vector split = fullname.split("."); - const String &name = split[0]; - String override_for = split.size() > 1 ? split[1] : String(); + const String &name = fullname.get_slicec('.', 0); + String override_for = fullname.get_slice_count(".") > 1 ? fullname.get_slicec('.', 1) : String(); if (builtins_with_overrides.has(name) && override_for.is_empty()) { // Builtin has an override but this particular one is not an override, so skip. diff --git a/doc/classes/String.xml b/doc/classes/String.xml index 547f198dbc1..3e18f05c228 100644 --- a/doc/classes/String.xml +++ b/doc/classes/String.xml @@ -331,7 +331,7 @@ Splits the string using a [param delimiter] and returns the substring at index [param slice]. Returns the original string if [param delimiter] does not occur in the string. Returns an empty string if the [param slice] does not exist. - This is faster than [method split], if you only need one substring. + This is faster than [method split], if you only need one or two substrings. [codeblock] print("i/am/example/hi".get_slice("/", 2)) # Prints "example" [/codeblock] @@ -342,6 +342,11 @@ Returns the total number of slices when the string is split with the given [param delimiter] (see [method split]). + Use [method get_slice] to extract a specific slice. + [codeblock] + print("i/am/example/string".get_slice_count("/")) # Prints '4'. + print("i am example string".get_slice_count("/")) # Prints '1'. + [/codeblock] @@ -350,7 +355,8 @@ Splits the string using a Unicode character with code [param delimiter] and returns the substring at index [param slice]. Returns an empty string if the [param slice] does not exist. - This is faster than [method split], if you only need one substring. + This is faster than [method split], if you only need one or two substrings. + This is a Unicode version of [method get_slice]. diff --git a/editor/debugger/script_editor_debugger.cpp b/editor/debugger/script_editor_debugger.cpp index b1b587d1ff1..bee3c662446 100644 --- a/editor/debugger/script_editor_debugger.cpp +++ b/editor/debugger/script_editor_debugger.cpp @@ -1879,7 +1879,7 @@ void ScriptEditorDebugger::_item_menu_id_pressed(int p_option) { } // Parse back the `file:line @ method()` string. - const Vector file_line_number = ci->get_text(1).split("@")[0].strip_edges().split(":"); + const Vector file_line_number = ci->get_text(1).get_slicec('@', 0).strip_edges().split(":"); ERR_FAIL_COND_MSG(file_line_number.size() < 2, "Incorrect C++ source stack trace file:line format (please report)."); const String &file = file_line_number[0]; const int line_number = file_line_number[1].to_int(); diff --git a/editor/inspector/editor_inspector.cpp b/editor/inspector/editor_inspector.cpp index 72ba1cf096e..d8edb65f738 100644 --- a/editor/inspector/editor_inspector.cpp +++ b/editor/inspector/editor_inspector.cpp @@ -3783,10 +3783,9 @@ void EditorInspector::update_tree() { subgroup = p.name; subgroup_togglable_property = nullptr; - Vector hint_parts = p.hint_string.split(","); - subgroup_base = hint_parts[0]; - if (hint_parts.size() > 1) { - section_depth = hint_parts[1].to_int(); + subgroup_base = p.hint_string.get_slicec(',', 0); + if (p.hint_string.get_slice_count(",") > 1) { + section_depth = p.hint_string.get_slicec(',', 1).to_int(); } else { section_depth = 0; } @@ -3798,10 +3797,9 @@ void EditorInspector::update_tree() { group = p.name; group_togglable_property = nullptr; - Vector hint_parts = p.hint_string.split(","); - group_base = hint_parts[0]; - if (hint_parts.size() > 1) { - section_depth = hint_parts[1].to_int(); + group_base = p.hint_string.get_slicec(',', 0); + if (p.hint_string.get_slice_count(",") > 1) { + section_depth = p.hint_string.get_slicec(',', 1).to_int(); } else { section_depth = 0; } diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp index b27faecd4ca..97d7621bed5 100644 --- a/editor/inspector/editor_properties.cpp +++ b/editor/inspector/editor_properties.cpp @@ -835,11 +835,10 @@ void EditorPropertyEnum::setup(const Vector &p_options) { HashMap> items; int64_t current_val = 0; for (const String &option : p_options) { - Vector text_split = option.split(":"); - if (text_split.size() != 1) { - current_val = text_split[1].to_int(); + if (option.get_slice_count(":") != 1) { + current_val = option.get_slicec(':', 1).to_int(); } - items[current_val].push_back(text_split[0]); + items[current_val].push_back(option.get_slicec(':', 0)); current_val += 1; } diff --git a/editor/scene/2d/tiles/tile_set_atlas_source_editor.cpp b/editor/scene/2d/tiles/tile_set_atlas_source_editor.cpp index 30716e05c38..6482b00aaf3 100644 --- a/editor/scene/2d/tiles/tile_set_atlas_source_editor.cpp +++ b/editor/scene/2d/tiles/tile_set_atlas_source_editor.cpp @@ -867,7 +867,7 @@ void TileSetAtlasSourceEditor::_update_current_tile_data_editor() { // Find the property to use. String property; if (tools_button_group->get_pressed_button() == tool_select_button && tile_inspector->is_visible() && !tile_inspector->get_selected_path().is_empty()) { - Vector components = tile_inspector->get_selected_path().split("/"); + Vector components = tile_inspector->get_selected_path().split("/", true, 1); if (components.size() >= 1) { property = components[0]; diff --git a/editor/script/script_create_dialog.cpp b/editor/script/script_create_dialog.cpp index 6395c7b8e2f..07da3b583a3 100644 --- a/editor/script/script_create_dialog.cpp +++ b/editor/script/script_create_dialog.cpp @@ -492,7 +492,7 @@ void ScriptCreateDialog::_file_selected(const String &p_file) { } void ScriptCreateDialog::_create() { - parent_name->set_text(select_class->get_selected_type().split(" ")[0]); + parent_name->set_text(select_class->get_selected_type().get_slicec(' ', 0)); _parent_name_changed(parent_name->get_text()); } diff --git a/editor/shader/visual_shader_editor_plugin.cpp b/editor/shader/visual_shader_editor_plugin.cpp index bb6562a9b17..ca6f6a322d4 100644 --- a/editor/shader/visual_shader_editor_plugin.cpp +++ b/editor/shader/visual_shader_editor_plugin.cpp @@ -1668,7 +1668,7 @@ void VisualShaderEditor::add_custom_type(const String &p_name, const String &p_t ao.is_native = !p_type.is_empty(); bool begin = false; - String root = p_category.split("/")[0]; + String root = p_category.get_slicec('/', 0); for (int i = 0; i < add_options.size(); i++) { if (add_options[i].is_custom) { diff --git a/modules/gdscript/language_server/gdscript_workspace.cpp b/modules/gdscript/language_server/gdscript_workspace.cpp index 4670f64f81a..c08fcccac1a 100644 --- a/modules/gdscript/language_server/gdscript_workspace.cpp +++ b/modules/gdscript/language_server/gdscript_workspace.cpp @@ -773,9 +773,8 @@ const LSP::DocumentSymbol *GDScriptWorkspace::resolve_symbol(const LSP::TextDocu String path = get_file_path(p_doc_pos.textDocument.uri); if (const ExtendGDScriptParser *parser = get_parse_result(path)) { String symbol_identifier = p_symbol_name; - Vector identifier_parts = symbol_identifier.split("("); - if (identifier_parts.size()) { - symbol_identifier = identifier_parts[0]; + if (symbol_identifier.get_slice_count("(") > 0) { + symbol_identifier = symbol_identifier.get_slicec('(', 0); } LSP::Position pos = p_doc_pos.position; diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 2f495b1539c..e7b5f4c2dc0 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -602,7 +602,7 @@ Vector OS_Android::get_system_font_path_for_text(const String &p_font_na font_name = font_aliases[font_name]; } String root = String(getenv("ANDROID_ROOT")).path_join("fonts"); - String lang_prefix = p_locale.split("_")[0]; + String lang_prefix = p_locale.get_slicec('_', 0); Vector ret; int best_score = 0; for (const List::Element *E = fonts.front(); E; E = E->next()) { diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index e99e513ca96..3c73cf3d03c 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -210,7 +210,7 @@ String OS_LinuxBSD::get_processor_name() const { while (!f->eof_reached()) { const String line = f->get_line(); if (line.to_lower().contains("model name")) { - return line.split(":")[1].strip_edges(); + return line.get_slicec(':', 1).strip_edges(); } } #endif @@ -295,7 +295,7 @@ String OS_LinuxBSD::get_systemd_os_release_info_value(const String &key) const { while (!f->eof_reached()) { const String line = f->get_line(); if (line.contains(key)) { - String value = line.split("=")[1].strip_edges(); + String value = line.get_slicec('=', 1).strip_edges(); value = value.trim_prefix("\""); return value.trim_suffix("\""); } diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp index f9a70902c5b..b779844a13a 100644 --- a/scene/animation/animation_node_state_machine.cpp +++ b/scene/animation/animation_node_state_machine.cpp @@ -1534,9 +1534,7 @@ bool AnimationNodeStateMachine::_can_connect(const StringName &p_name) { } String node_name = p_name; - Vector path = node_name.split("/"); - - if (path.size() < 2) { + if (node_name.get_slice_count("/") < 2) { return false; } diff --git a/scene/debugger/scene_debugger.cpp b/scene/debugger/scene_debugger.cpp index 36ef16acac5..1b567c72623 100644 --- a/scene/debugger/scene_debugger.cpp +++ b/scene/debugger/scene_debugger.cpp @@ -647,10 +647,11 @@ void SceneDebugger::_set_object_property(ObjectID p_id, const String &p_property return; } - String prop_name = p_property; + String prop_name; if (p_property.begins_with("Members/")) { - Vector ss = p_property.split("/"); - prop_name = ss[ss.size() - 1]; + prop_name = p_property.get_slicec('/', p_property.get_slice_count("/") - 1); + } else { + prop_name = p_property; } Variant value; diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp index a2abb10d7a4..3e1c4c84246 100644 --- a/scene/resources/visual_shader.cpp +++ b/scene/resources/visual_shader.cpp @@ -4835,8 +4835,7 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) { int count = 0; int index = 0; for (int i = 0; i < inputs_strings.size(); i++) { - Vector arr = inputs_strings[i].split(","); - if (arr[0].to_int() == p_id) { + if (inputs_strings[i].get_slicec(',', 0).to_int() == p_id) { count = inputs_strings[i].size(); break; } @@ -4848,7 +4847,7 @@ void VisualShaderNodeGroupBase::remove_input_port(int p_id) { inputs = inputs.substr(0, index); for (int i = p_id; i < inputs_strings.size(); i++) { - inputs += inputs_strings[i].replace_first(inputs_strings[i].split(",")[0], itos(i)) + ";"; + inputs += inputs_strings[i].replace_first(inputs_strings[i].get_slicec(',', 0), itos(i)) + ";"; } _apply_port_changes(); @@ -4910,8 +4909,7 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) { int count = 0; int index = 0; for (int i = 0; i < outputs_strings.size(); i++) { - Vector arr = outputs_strings[i].split(","); - if (arr[0].to_int() == p_id) { + if (outputs_strings[i].get_slicec(',', 0).to_int() == p_id) { count = outputs_strings[i].size(); break; } @@ -4923,7 +4921,7 @@ void VisualShaderNodeGroupBase::remove_output_port(int p_id) { outputs = outputs.substr(0, index); for (int i = p_id; i < outputs_strings.size(); i++) { - outputs += outputs_strings[i].replace_first(outputs_strings[i].split(",")[0], itos(i)) + ";"; + outputs += outputs_strings[i].replace_first(outputs_strings[i].get_slicec(',', 0), itos(i)) + ";"; } _apply_port_changes(); diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h index 5e707092f21..a526af03e43 100644 --- a/scene/resources/visual_shader.h +++ b/scene/resources/visual_shader.h @@ -97,13 +97,12 @@ public: name(p_name), mode(p_mode), type(p_type) {} bool from_string(const String &p_str) { - Vector arr = p_str.split(","); - if (arr.size() != 2) { + if (p_str.get_slice_count(",") != 2) { return false; } - mode = (VaryingMode)arr[0].to_int(); - type = (VaryingType)arr[1].to_int(); + mode = (VaryingMode)p_str.get_slicec(',', 0).to_int(); + type = (VaryingType)p_str.get_slicec(',', 1).to_int(); return true; }