In the EUPHORIA 4.0 Standard Library there are many that take some notion of a needle and haystack: You can conceptually divide these into five classes depending on what kind of object you take as the 'needle'.
Consider s a haystack and x a needle and the abstract notion of matching. A match is indicated by a beginning i and an ending j. Depending on what kind of needle you have you have a different operational definition of a match:
Objects have a degree. An atom has a degree 0; a string a degree of 1. A sequence of degree 2 contains string as members such as a list of names.
|description||simple member2||any member||slice||regular expression slice||wildcard||degree change|
|match a needle forwards and return an index||find(x,s)||find_any(x,s)||match(x,s)||See note 3||variable|
|match a needle backwards and return an index||rfind(x,s)||rmatch(x,s)||to 0|
|match needle and return all indecies||find_all(x,s)||match_all(x,s)||re:match_all(x,s)||variable|
|split based on some needle||split_any(x,s)||split(x,s)||re:split(x,s)||+1|
|Replace all data matching needle with some other supplied data||mapping||replace_all||re:find_replace||no change|
|Replace all data matching with some other supplied data to some limit||search:find_replace||search:match_replace, replace (limit is always 1)||re:find_replace_limit||no change|
|Removing Data and its place1||remove_item, remove_all||no change|
|Inserting data and its place1||add_item||no change|
|Indicate whether the needle matches the entire string||length(s)=1 and equal(x,s)||is_in_list(s,x)||equal(s,x)||re:is_match(x,s)||wildcard:is_match(x,s)||to 0, boolean|
|Indicate whether the needle matches a portion of the string||match_any(x,s)||re:has_match||to 0, boolean|
|description||single index||many indicies||slice||deep index|
|retrieve a value with an index|| operator||extract, project||slice, [..] operator||fetch|
|Overwriting a value into a sequence at some index|| =||patch||store|
|Insert Item and providing its place||insert||splice|
These tables are neither brief nor complete. With a more complete table you might see how one could profit from these similarities. You might not be able to remember the slice needle routine names and you can look them up in this table. You might decide it would be a good idea to alias them to the similar names or even the same names thanks to namespaces. To make data encapsulation for these kinds of operations you would need a file for every kind of needle: We already have different files for wildcard, regex. You can create one for any-item needles, one for slice needles and one for item needles.
There is only one wildcard routine, is_match. Others can be easily built up based on this routine and its only known advantage is simplicity. For user interfaces this might be what you want. This is the same used in searching for files. Needles and haystacks are supposed to be strings but there is no indication in the documentation that they must be.
Slice and member needles are the basic versions that have been with us from the early days of EUPHORIA. Also easy to use like wildcards but less powerful than wildcard needles. These are not limited to string data.
Any Member needles, like slice and member are not limited to strings and needles must be the same degree as the haystack. This means for searching a list of strings you must use another list of strings. Useful internally in a program to be sure but not for regular end user input.
Regular expression needles have the most complete set of functions and options I have ever seen. In terms of completeness and its unique subgroups it really is in a completely different class. However, both the needle and the haystack must be UTF-8 compliant strings unlike the other needle/haystack routines you will have to convert. For the user, you might correctly judge that most users don't want this and use it only internally in your application. I would be disappointed though.