(39) 's Extra Blueprint Nodes for You as a Plugin, No C++ Required!

Hello ,

I had to write a custom BP node for a project I am working on. I thought I would share it with the community. Since you already have a good package of BP nodes, perhaps you could integrate into yours.

Node: ExplodeString
Description: Splits a string based on given delimiter. Unlike the ParseIntoArray() function, the delimiter can be a multi-character string (eg ‘::’). There is also aan optional automatic trimming that will cleanup the returned substrings.

I am attaching the source here and if anyone is interested, have fun :). Please note that currently it is implemented as a BlueprintFunctionLibrary, you might want to change that to suit your needs.

UStringUtils.h


#pragma once

#include "StringUtils.generated.h"

/**
 * 
 */
UCLASS()
class UStringUtils : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

	/**
	* Split a string into an array of substrings based on the given delimitter.
	* Unlike ParseIntoArray() function which expects single character delimitters,  function can accept a delimitter that is also a string.
	*
	* @param InputString - The string that is to be exploded.
	* @param Separator - The delimitter that is used for splitting (multi character strings are allowed)
	* @param limit - If greater than zero, returns only the first x strings. Otherwsie returns  the substrings
	* @param bTrimElelements - If True, then each subsctring is processed and any leading or trailing whitespcaes are trimmed.
	*/
	UFUNCTION(BlueprintPure, meta = (FriendlyName = "Explode string", Keywords = "split explode string"), Category = String)
	static TArray<FString> ExplodeString(FString InputString, FString Separator = ",", int32 limit = 0, bool bTrimElements = false);
	
};

UStringUtils.cpp



#include "YourGame.h" //<-  Change  to match your-own header file
#include "StringUtils.h"


UStringUtils::UStringUtils(const class FPostConstructInitializeProperties& PCIP)
	: Super(PCIP)
{

}

TArray<FString> UStringUtils::ExplodeString(FString InputString, FString Separator, int32 limit, bool bTrimElements)
{
	TArray<FString> OutputStrings;

	if (InputString.Len() > 0 && Separator.Len() > 0) {
		int32 StringIndex = 0;
		int32 SeparatorIndex = 0;

		FString Section = "";
		FString Extra = "";

		int32 PartialMatchStart = -1;

		while (StringIndex < InputString.Len()) {

			if (InputString[StringIndex] == Separator[SeparatorIndex]) {
				if (SeparatorIndex == 0) {
					//A new partial match has started.
					PartialMatchStart = StringIndex;
				}
				Extra.AppendChar(InputString[StringIndex]);
				if (SeparatorIndex == (Separator.Len() - 1)) {
					//We have matched the entire separator.
					SeparatorIndex = 0;
					PartialMatchStart = -1;
					if (bTrimElements == true) {
						OutputStrings.Add(FString(Section).Trim().TrimTrailing());
					}
					else {
						OutputStrings.Add(FString(Section));
					}

					//if we have reached the limit, stop.
					if (limit > 0 && OutputStrings.Num() >= limit) {
						return OutputStrings;
					}

					Extra.Empty();
					Section.Empty();
				}
				else {
					++SeparatorIndex;
				}
			}
			else {
				//Not matched.
				//We should revert back to PartialMatchStart+1 (if there was a partial match) and clear away extra.
				if (PartialMatchStart >= 0) {
					StringIndex = PartialMatchStart;
					PartialMatchStart = -1;
					Extra.Empty();
					SeparatorIndex = 0;
				}
				Section.AppendChar(InputString[StringIndex]);
			}

			++StringIndex;
		}

		//If there is anything left in Section or Extra. They should be added as a new entry.
		if (bTrimElements == true) {
			OutputStrings.Add(FString(Section + Extra).Trim().TrimTrailing());
		}
		else {
			OutputStrings.Add(FString(Section + Extra));
		}

		Section.Empty();
		Extra.Empty();
	}

	return OutputStrings;
}




Usage and sample output: