I am writing some code for someone and wanted to show them different ways they could count the no of times a character/no occur in a longer string using both IEnumerable and RegEx however I have found that when I am trying to count the no of times a number occurs in a string none of my methods work despite me converting the no into a literal character first. However trying to use a variable and the cast methods does not work e.g:
char chr = '2'; // works fine
So this literal works however all the other ways which I need to be able to use on variables such as converting an int variable into a char with either (char)no or Convert.ToChar(no) doesn’t work for some reason.
I am sure there is a simple reason but I cannot seem to crack it.
This is my code, the reason there are two methods using RegEx is that I was testing the best way to count special characters such as dots . in a string with C#.
I didn’t know whether it was best to just RegEx.Escape any variable being passed in to my count method or whether I needed to check first whether it needed to be escaped before doing so or just leaving the character alone.
The code calling the test functions is below, the reason I am using a static class to log out the errors is I am just adding this method into a bigger project to do the test quickly and all the HelperLib class is used for is logging with adding a date stamp next to each line, debugging, setting up system wide settings on load and so on…
private void TestCode()
{
this.HelperLib.LogMsg("IN TestCode - Run Tests on numbers");
string word = "22.2.34.3";
int no = 2;
// char chr = (char)(no); // converting a variable which I need to do doesn't work
char chr = Convert.ToChar(no) // doesn't work
// char chr = '2'; // when we do it as a literal it works
// correct amount of 2 (as a char) in the string should be 3 but we get 0 for each attempt
int a = word.CountChars(chr);
HelperLib.LogMsg("Use IEnumerable.Count; There are " + a.ToString() + " occurrences of " + chr.ToString() + " in " + word);
int b = word.CountChars2(chr);
HelperLib.LogMsg("RegEx.Escape all chars; There are " + b.ToString() + " occurrences of " + chr.ToString() + " in " + word);
int c = word.CountChars3(chr);
HelperLib.LogMsg("Test for special char first before escaping; There are " + c.ToString() + " occurrences of " + chr.ToString() + " in " + word,);
return;
}
And the methods I am using are in an Extensions class so I can just add them to strings.
public static int CountChars(this string value, char letter)
{
int count = value.Count(ch => ch == letter);
return count;
}
public static int CountChars2(this string value, char letter)
{
// if the letter is a special char then escape it otherwise leave it alone
string re = (letter.IsSpecialChar()) ? Regex.Escape(letter.ToString()) : letter.ToString();
int c = Regex.Matches(value, re, RegexOptions.IgnoreCase).Count;
return c;
}
public static int CountChars3(this string value, char letter)
{
// escape all characters passed in, in case its a special character
string re = Regex.Escape(letter.ToString());
int c = Regex.Matches(value, re, RegexOptions.IgnoreCase).Count;
return c;
}
// test to see if we need to escape a character that is a special character in RegEx
public static bool IsSpecialChar(this char letter)
{
char[] x = { '.', '\', '+', '*', '?', '[', ']', '$', '(', ')', '{', '}', '=', '!', '<', '>', '|', ':', ':', '-', '#' };
bool ret = (x.Contains(letter)) ? true : false;
return ret;
}
And the debug I get back is below…
10/12/2021 23:11:28 - IN TestCode - Run Tests on numbers;
10/12/2021 23:11:28 - Use IEnumerable.Count; There are 0 occurrences of 2 in 22.2.34.3;
10/12/2021 23:11:28 - RegEx.Escape all chars; There are 0 occurrences of 2 in 22.2.34.3;
10/12/2021 23:11:28 - Test for special char first before escaping; There are 0 occurrences of 2 in 22.2.34.3;
So I can count letters including special characters used in RegEx like dots without a problem but when it comes to numbers even converting them to a character first doesn’t seem to work and I am stuck to why this is occurring as a literal ‘2’ works but a variable converted to a Char doesn’t.
Also when using JavaScript, as I have a test page for testing expressions before using them in whatever language I need, I have found that escaping every character doesn’t work when it comes to numbers OR special characters for example with the same string “22.2.34.3” when I try 2 it return 0 matches but just 2 returns 3 with this code:
// returns 0
var value = "22.2.34.3";
re = "2"; // tried with double \ and triple \
var exp = new RegExp(re,"gi");
var no = value.match(exp)||[];
alert("NO OF MATCHES " + no.length);
// returns 3
var value = "22.2.34.3";
re = "2";
var exp = new RegExp(re,"gi");
var no = value.match(exp)||[];
alert("NO OF MATCHES " + no.length);
What does a single escaping backslash next to a digit mean to the RegEx machine as it works with letters except special RegEx characters like d or w however I thought by escaping those characters it would mean they would be treated like literals not special characters (digit, word char) etc?
Therefore in JavaScript what would I need to do to count the number of a single no in a longer number e.g “2” in “22.2.34.3” OR count the number of character “d” in a string like “does it matter don’t do it” as a single escape string doesn’t work with the code I am using shown above (or a double/triple backslash)??
Any help in understanding this would be appreciated. Thanks.