{"id":1489,"date":"2018-04-23T14:28:11","date_gmt":"2018-04-23T12:28:11","guid":{"rendered":"http:\/\/hen.co.za\/blog\/?p=1489"},"modified":"2018-04-23T15:03:11","modified_gmt":"2018-04-23T13:03:11","slug":"more-advanced-contain-string-function","status":"publish","type":"post","link":"https:\/\/hen.co.za\/blog\/2018\/04\/more-advanced-contain-string-function\/","title":{"rendered":"More advanced Contain string function"},"content":{"rendered":"<p>Just thought I share this useful function I&#8217;ve been using recently to enhance some of my applications to make text\/string searching more powerful.<\/p>\n<p>If you want to allow things like &#8216;and&#8217;, &#8216;or&#8217; and &#8216;not&#8217; in a text filter this could be useful to you. Additionally I also added keywords for things like &#8216;matchexactly&#8217;, &#8216;startswith&#8217; and &#8216;endswith&#8217;.<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\npublic static class StringCompareUtils\r\n{\r\n  public static bool ContainEx(string source, string findText, bool caseSensitive = false)\r\n  {\r\n    bool found = false;\r\n    string lowerCasefindText = findText.ToLower();\r\n    if (findText.Trim().Length == 0)\r\n    {\r\n      found = true;\r\n    }\r\n    else if (lowerCasefindText.Contains(&quot; and &quot;))\r\n    {\r\n      string&#x5B;] parts = findText.Split(new string&#x5B;] { &quot; and &quot;, &quot; AND &quot; }, StringSplitOptions.RemoveEmptyEntries);\r\n      found = true;\r\n      foreach (string part in parts)\r\n      {\r\n        if (!ContainEx(source, part))\r\n        {\r\n          found = false;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n    else if (lowerCasefindText.Contains(&quot; or &quot;))\r\n    {\r\n      string&#x5B;] parts = findText.Split(new string&#x5B;] { &quot; or &quot;, &quot; OR &quot; }, StringSplitOptions.RemoveEmptyEntries);\r\n      foreach (string part in parts)\r\n      {\r\n        if (ContainEx(source, part))\r\n        {\r\n          found = true;\r\n          break;\r\n        }\r\n      }\r\n    }\r\n    else\r\n    {\r\n      if (lowerCasefindText.TrimStart().StartsWith(&quot;not &quot;))\r\n      {\r\n        found = !source.ContainEx2(findText.TrimStart().Substring(4), caseSensitive);\r\n      }\r\n      else\r\n        found = source.ContainEx2(findText, caseSensitive);\r\n    }\r\n    return found;\r\n  }\r\n  private static bool ContainEx2(this string text, string findText, bool caseSensitive = false)\r\n  {\r\n    string matchText = caseSensitive ? text : text.ToLower();\r\n    string matchFindText = caseSensitive ? findText : findText.ToLower();\r\n    if (matchFindText.ToLower().StartsWith(&quot;matchexactly &quot;))\r\n    {\r\n      return text == findText.Substring(&quot;matchexactly &quot;.Length);\r\n    }\r\n    else if (findText.ToLower().StartsWith(&quot;startswith &quot;))\r\n    {\r\n      return text.StartsWith(findText.Substring(&quot;startswith &quot;.Length));\r\n    }\r\n    else if (findText.ToLower().StartsWith(&quot;endswith &quot;))\r\n    {\r\n      return text.EndsWith(findText.Substring(&quot;endswith &quot;.Length));\r\n    }\r\n    else\r\n    {\r\n      return text.Contains(findText);\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>The default behavior is like the &#8216;like&#8217; operator (text contains search filter). This allow you to find a string like &#8216;are&#8217; in &#8216;You are welcome&#8217;. Using this function you can specify a filter like &#8216;startswith You&#8217; or &#8216;endswith welcome&#8217;.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Just thought I share this useful function I&#8217;ve been using recently to enhance some of my applications to make text\/string searching more powerful. If you want to allow things like &#8216;and&#8217;, &#8216;or&#8217; and &#8216;not&#8217; in a text filter this could &hellip;<\/p>\n<p class=\"read-more\"><a href=\"https:\/\/hen.co.za\/blog\/2018\/04\/more-advanced-contain-string-function\/\">Read more &raquo;<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3],"tags":[8,303,24],"class_list":["post-1489","post","type-post","status-publish","format-standard","hentry","category-development","tag-c","tag-development","tag-tip"],"_links":{"self":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/1489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/comments?post=1489"}],"version-history":[{"count":2,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/1489\/revisions"}],"predecessor-version":[{"id":1492,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/posts\/1489\/revisions\/1492"}],"wp:attachment":[{"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/media?parent=1489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/categories?post=1489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hen.co.za\/blog\/wp-json\/wp\/v2\/tags?post=1489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}