Check if a string contains an element from a list (of strings)

后端 未结 11 1995
盖世英雄少女心
盖世英雄少女心 2020-11-27 11:09

For the following block of code:

For I = 0 To listOfStrings.Count - 1
    If myString.Contains(lstOfStrings.Item(I)) Then
        Return True
    End If
Next         


        
相关标签:
11条回答
  • 2020-11-27 11:16

    With LINQ, and using C# (I don't know VB much these days):

    bool b = listOfStrings.Any(s=>myString.Contains(s));
    

    or (shorter and more efficient, but arguably less clear):

    bool b = listOfStrings.Any(myString.Contains);
    

    If you were testing equality, it would be worth looking at HashSet etc, but this won't help with partial matches unless you split it into fragments and add an order of complexity.


    update: if you really mean "StartsWith", then you could sort the list and place it into an array ; then use Array.BinarySearch to find each item - check by lookup to see if it is a full or partial match.

    0 讨论(0)
  • 2020-11-27 11:20

    As I needed to check if there are items from a list in a (long) string, I ended up with this one:

    listOfStrings.Any(x => myString.ToUpper().Contains(x.ToUpper()));
    

    Or in vb.net:

    listOfStrings.Any(Function(x) myString.ToUpper().Contains(x.ToUpper()))
    
    0 讨论(0)
  • 2020-11-27 11:23

    Have you tested the speed?

    i.e. Have you created a sample set of data and profiled it? It may not be as bad as you think.

    This might also be something you could spawn off into a separate thread and give the illusion of speed!

    0 讨论(0)
  • 2020-11-27 11:25

    I liked Marc's answer, but needed the Contains matching to be CaSe InSenSiTiVe.

    This was the solution:

    bool b = listOfStrings.Any(s => myString.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0))
    
    0 讨论(0)
  • 2020-11-27 11:30

    If speed is critical, you might want to look for the Aho-Corasick algorithm for sets of patterns.

    It's a trie with failure links, that is, complexity is O(n+m+k), where n is the length of the input text, m the cumulative length of the patterns and k the number of matches. You just have to modify the algorithm to terminate after the first match is found.

    0 讨论(0)
  • 2020-11-27 11:32

    There were a number of suggestions from an earlier similar question "Best way to test for existing string against a large list of comparables".

    Regex might be sufficient for your requirement. The expression would be a concatenation of all the candidate substrings, with an OR "|" operator between them. Of course, you'll have to watch out for unescaped characters when building the expression, or a failure to compile it because of complexity or size limitations.

    Another way to do this would be to construct a trie data structure to represent all the candidate substrings (this may somewhat duplicate what the regex matcher is doing). As you step through each character in the test string, you would create a new pointer to the root of the trie, and advance existing pointers to the appropriate child (if any). You get a match when any pointer reaches a leaf.

    0 讨论(0)
提交回复
热议问题