This is a common task when dealing with strings. It isn't as powerful as regular expressions, but is a quick win for checking a string. Partial string match, contains, is a simple concept and D hides it a little bit.
import std.algorithm; auto haystack = "some long name"; auto needle = "long"; if(!haystack.find(needle).empty) haystackHasNeedle(haystack);
In this context
! is negation, (not)... empty.
find is a general function that works on any range. So it can be used with numbers and other containers. Similar to
filter it is possible to specify more complex conditions.
import std.algorithm; auto haystack = [1, 2, 3, 4]; assert(haystack.find!(x => x > 2) .equal([3, 4]));
It is actually moving the start of the range where the condition matches leaving the rest of the range to be manipulated. This approach is carried to other functions and makes for a very consistent navigation of strings and other data.
import std.algorithm; auto haystack = "some long name"; if(haystack.skipOver("some")) assert(haystack.startsWith(" long"));
This post would seriously get long as I would end up going over almost all of std.algorithm and std.range due to all the general methods available.
Instead I must mention one critical aspect to strings. Unicode is not simple, while many algorithms with strings will work at this level, unicode has normalization, and graphemes to consider.
It is not like you'll fair better using another language. I generally haven't put much thought into it, I think the main two operations to reach for gragheme is character count and string reversal. I've generally had the luxury of ignoring this detail.