How to check if string contains the text in C# Winforms - c#

Can anyone help me in writing a piece of code in C# Winforms, which can give me a boolean value, that whether a piece of string contains a few words.
For example, If I want to check whether string test only string exists in string "Data is provided to test only string".
I have written following piece of code, but it alwys gives me true, whether string contains the words or nor.
private bool ContainsText(string input)
{
for (int i = 0; i < input.Length; i++)
{
if (((int)input[i] >= 65 && (int)input[i] <= 90) || ((int)input[i] >= 97 && (int)input[i] <= 177))
return true;
}
return false;
}
When I call the following line, I always get true, which is not correct
MessageBox.Show(ContainsText("test only string").ToString());

Code-wise, your ContainsText code immediately returns true if any character in input is either in "A to Z" or "a to U+00B1" for some reason.
But the problems lie deeper than that: you've described two inputs - the string to check for, e.g. "test only string" and the string to check for its presence, e.g. "Data is provided to test only string". Your method only accepts one input, and doesn't use any other state. So it can't possibly work. It's worth taking a step back and trying to work out why you didn't notice that you needed two inputs - and why indeed your test only used "test only string" and didn't mention "Data is provided to test only string".
You don't really need a method at all though - String already has a Contains method:
if (textToCheck.Contains(textToFind))
{
...
}
That's assuming you want an ordinal comparison. Use IndexOf with an appropriate StringComparison if you want to check in a culture-sensitive or case-insensitive way.

You can use Contains method of String object.
var a = "Data is provided to test only string";
var b = "test only string";
if (a.Contains(b))
MessageBox.Show("yes");

A simple string.IndexOf perhaps with the enum to ignore case:
string myTestString = "Data is provided to Test Only String";
if(myTestString.IndexOf("test only string", StringComparison.CurrentCultureIgnoreCase) >= 0)
Console.WriteLine("Found text");
Of course the string class has also a Contains method, but it is implemented as a call to IndexOf, without the possibility to ignore the case.
public bool Contains(string value)
{
return (this.IndexOf(value, StringComparison.Ordinal) >= 0);
}

Use IndexOf
http://www.dotnetperls.com/indexof
example of usage..
string str = "string to test";
bool result = str.IndexOf("The hosted network started.") != -1;
MessageBox.Show(result.ToString());

Related

Using List.Contains method to find a string returns false but manual comparison return true

I have a list of strings and I am trying to determine whether one of them match a needle string. That list of strings contains the needle at the first index, and my code has the following behavior:
listOfStrings.Contains(needle); // return false
listOfStrings[0] == needle; // return true
Why does the Contains method have a different behavior than the default comparison beahavior, and what should I modify so that it has the same be havior?
To give more insight about the problem I am facing, I am handling strings which come from WinForm textboxes. They represent input paths and a destination folder.
if (!destinationPath.EndsWith("\\"))
{
destinationPath += "\\";
}
List<string> inputDirectories = new List<string>(inputPaths.Length);
foreach (string path in inputPaths)
{
inputDirectories.Add(Path.GetDirectoryName(path).ToLower());
}
bool comparison1 = inputDirectories[0] == Path.GetDirectoryName(destinationPath.ToLower()); // return true
bool comparison2 = inputDirectories.Contains(Path.GetDirectoryName(destinationPath.ToLower())); // return false
You haven't said what Type your list is, but if it's an ArrayList or a List<object> the comparison will give a different result from List<string>, because the Compare method will compare objects rather than strings.
To understand this, try running the following code:
string s1 = "A";
string s2 = "AB";
s1 += "B";
Console.WriteLine(s1 == s2); // True
Console.WriteLine((object)s1 == (object)s2); // False
s1 and s2 are equal when compared as strings, but are different objects.
If you are already using List<string> and are looking for a case-insensitive Contains, try the technique in the accepted answer to this question.

String To Verify

I am a C#.net developer.
I wanted to check if a source string contained all of the characters in the destination string.
ex:
Source String : Test Check
Destination sting : Check Test
Then wanted to check if each char(T,e,s,t,c,h,e,c,k) are present in the destination string?
The source string can contain numeric/alphanumeric/special characters to compare with destination string.
We can verify by loop through each & every character from the destination and match that to destination but that would takes time.
Is there any simple way to check this?
You can use linq All method for this
string source = "Test Check";
string destination = "Check Test;
bool result = source.All(a => destination.Contains(a));
As #GrantWinney mentioned this solution won't take the number of letter occurences into consideration
You can use Except + Any:
string sourceString ="Test Check";
string destString ="Check Test";
bool destStringContainsSource = !sourceString.Except(destString).Any();
or with HashSet.SetEquals:
HashSet<char> set = new HashSet<char>(sourceString);
destStringContainsSource = set.SetEquals(destString);
Both approaches don't take the number of characters into account.
The Except-approach does not even check if the destination-string contains more characters. It's just checking if the second string is a subset of the first. SetEquals is not quite the same.
You can use HashSet.IsSubsetOf to get the same behaviour:
HashSet<char> set = new HashSet<char>(sourceString);
bool sourceIsSubsetOfDest = set.IsSubsetOf(destString);
I would prefer the HashSet approaches since they are very efficient and most of all clear.

Case Insensitive comparison in C# [duplicate]

This question already has answers here:
Case insensitive 'Contains(string)'
(29 answers)
Closed 9 years ago.
I am comparing two strings using following code
string1.Contains(string2)
but i am not getting results for case insensitive search. Moreover I cant use String.Compare coz i dont want to match the whole name as the name is very big.
My need is to have case insensitive search and the search text can be of any length which the String1 contains.
Eg Term************** is the name.
I enter "erm" in textbox den i get the result. but when i enter "term" i dont get any result.
Can anyone help me :)
Try this:
string.Equals("this will return true", "ThIs WiLL ReTurN TRue", StringComparison.CurrentCultureIgnoreCase)
Or, for contains:
if (string1.IndexOf(string2, StringComparison.CurrentCultureIgnoreCase) >= 0)
I prefer an extension method like this.
public static class StringExtensions
{
public static bool Contains(this string source, string value, StringComparison compareMode)
{
if (string.IsNullOrEmpty(source))
return false;
return source.IndexOf(value, compareMode) >= 0;
}
}
Notice that in this way you could avoid the costly transformation in upper or lower case.
You could call the extension using this syntax
bool result = "This is a try".Contains("TRY", StringComparison.InvariantCultureIgnoreCase);
Console.WriteLine(result);
Please note: the above extension (as true for every extension method) should be defined inside a non-nested, non-generic static class See MSDN Ref
Convert both strings to a same case, either upper or lower.
string1.ToUpper().Contains(string2.ToUpper());
Why not this:
if (string1.IndexOf(string2, StringComparison.OrdinalIgnoreCase) >= 0)
{
}
string1.ToUpperInvariant().Contains(string2.ToUpperInvariant());
You can either convert both strings to uppercase, or use regular expressions:
using System.Text.RegularExpressions;
class Program {
static void Main(string[] args) {
string string1 = "TermSomething";
string string2 = "term";
bool test1 = string1.ToUpperInvariant().Contains(string2.ToUpperInvariant());
bool test2 = Regex.IsMatch(string1, Regex.Escape(string2), RegexOptions.IgnoreCase);
}
}
Note that if you use regular expressions you should escape the search string, so that special regex characters are interpreted literally.
Regex.IsMatch(string1,string2,RegexOptions.IgnoreCase);
This returns boolean value.....

Find if string contains at least 2 characters similar to another? C#

I need a method to check if a string contains one or more similar characters to another. I dont want to find all strings containing the letter "D".
For example, if I have a string "Christopher" and want to see if "Chris" is contained in "Christopher", I want that to return. However, if I want to see if "Candy" is in the string "Christopher", I wont want it to return just because it has a "C" in common.
I have tried the .Contains() method but cant give that rules for 2 or more similar characters and I have thought about using regular expressions but that might be a bit over kill. The similar letters must be next to eachother.
Thank you :)
This looks for each 2-character-gram of s1 and looks for it in s2.
string s1 = "Chrx";
string s2 = "Christopher";
IsMatchOn2Characters(s1, s2);
static bool IsMatchOn2Characters(string a, string b)
{
string s1 = a.ToLowerInvariant();
string s2 = b.ToLowerInvariant();
for (int i = 0; i < s1.Length - 1; i++)
{
if (s2.IndexOf(s1.Substring(i,2)) >= 0)
return true; // match
}
return false; // no match
}
This looks a lot like a longest common substring problem. This can be solved easily using DP in O(m*n).
If you are not worried about performance and don't really want to implement this, you can also go with the brute force solution of searching every substring of s1 into s2.

How to validate that a string doesn't contain HTML using C#

Does anyone have a simple, efficient way of checking that a string doesn't contain HTML? Basically, I want to check that certain fields only contain plain text. I thought about looking for the < character, but that can easily be used in plain text. Another way might be to create a new System.Xml.Linq.XElement using:
XElement.Parse("<wrapper>" + MyString + "</wrapper>")
and check that the XElement contains no child elements, but this seems a little heavyweight for what I need.
The following will match any matching set of tags. i.e. <b>this</b>
Regex tagRegex = new Regex(#"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>");
The following will match any single tag. i.e. <b> (it doesn't have to be closed).
Regex tagRegex = new Regex(#"<[^>]+>");
You can then use it like so
bool hasTags = tagRegex.IsMatch(myString);
You could ensure plain text by encoding the input using HttpUtility.HtmlEncode.
In fact, depending on how strict you want the check to be, you could use it to determine if the string contains HTML:
bool containsHTML = (myString != HttpUtility.HtmlEncode(myString));
Here you go:
using System.Text.RegularExpressions;
private bool ContainsHTML(string checkString)
{
return Regex.IsMatch(checkString, "<(.|\n)*?>");
}
That is the simplest way, since items in brackets are unlikely to occur naturally.
I just tried my XElement.Parse solution. I created an extension method on the string class so I can reuse the code easily:
public static bool ContainsXHTML(this string input)
{
try
{
XElement x = XElement.Parse("<wrapper>" + input + "</wrapper>");
return !(x.DescendantNodes().Count() == 1 && x.DescendantNodes().First().NodeType == XmlNodeType.Text);
}
catch (XmlException ex)
{
return true;
}
}
One problem I found was that plain text ampersand and less than characters cause an XmlException and indicate that the field contains HTML (which is wrong). To fix this, the input string passed in first needs to have the ampersands and less than characters converted to their equivalent XHTML entities. I wrote another extension method to do that:
public static string ConvertXHTMLEntities(this string input)
{
// Convert all ampersands to the ampersand entity.
string output = input;
output = output.Replace("&", "amp_token");
output = output.Replace("&", "&");
output = output.Replace("amp_token", "&");
// Convert less than to the less than entity (without messing up tags).
output = output.Replace("< ", "< ");
return output;
}
Now I can take a user submitted string and check that it doesn't contain HTML using the following code:
bool ContainsHTML = UserEnteredString.ConvertXHTMLEntities().ContainsXHTML();
I'm not sure if this is bullet proof, but I think it's good enough for my situation.
this also checks for things like < br /> self enclosed tags with optional whitespace. the list does not contain new html5 tags.
internal static class HtmlExts
{
public static bool containsHtmlTag(this string text, string tag)
{
var pattern = #"<\s*" + tag + #"\s*\/?>";
return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
}
public static bool containsHtmlTags(this string text, string tags)
{
var ba = tags.Split('|').Select(x => new {tag = x, hastag = text.containsHtmlTag(x)}).Where(x => x.hastag);
return ba.Count() > 0;
}
public static bool containsHtmlTags(this string text)
{
return
text.containsHtmlTags(
"a|abbr|acronym|address|area|b|base|bdo|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|DOCTYPE|dt|em|fieldset|form|h1|h2|h3|h4|h5|h6|head|html|hr|i|img|input|ins|kbd|label|legend|li|link|map|meta|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var");
}
}
Angle brackets may not be your only challenge. Other characters can also be potentially harmful script injection. Such as the common double hyphen "--", which can also used in SQL injection. And there are others.
On an ASP.Net page, if validateRequest = true in machine.config, web.config or the page directive, the user will get an error page stating "A potentially dangerous Request.Form value was detected from the client" if an HTML tag or various other potential script-injection attacks are detected. You probably want to avoid this and provide a more elegant, less-scary UI experience.
You could test for both the opening and closing tags <> using a regular expression, and allow the text if only one of them occcurs. Allow < or >, but not < followed by some text and then >, in that order.
You could allow angle brackets and HtmlEncode the text to preserve them when the data is persisted.
Beware when using the HttpUtility.HtmlEncode method mentioned above. If you are checking some text with special characters, but not HTML, it will evaluate incorrectly. Maybe that's why J c used "...depending on how strict you want the check to be..."

Categories