This question already has answers here:
C# snippet needed to replicate VBA Like operator
(3 answers)
Closed 8 years ago.
Q: I want to match string with pattern that has wild cards(* and ?). I know in VB.Net, I can do this with Like Operator but how do I do in C#?
Example in VB:
Private Sub Match()
Dim testCheck As Boolean
testCheck = "apple" Like "*p?e"
End Sub
Q: Code in C#?
In C#, you can use regular expressions:
bool matches = Regex.IsMatch("apple", ".*p.e");
Replacing:
* with .* (multiple characters, zero or more)
? with . (one character)
There is no operator like that in c#.
VB.NET compiles your code to following LikeOperator.LikeString method call:
bool testCheck = LikeOperator.LikeString("apple", "*p?e", CompareMethod.Binary);
You can call this method directly if you add reference to Microsoft.VisualBasic.dll and add using Microsoft.VisualBasic.CompilerServices, but I would not advise doing that.
You should probably learn regular expressions and use proper regex instead of Like operator. Expression equivalent to yours would be:
.*p.e
As others have pointed out, this is probably a job for regular expressions.
Nonetheless, I thought it might be fun to write a tiny extension method that implements this logic and came up with the following:
static class StringCompareExtensions
{
public static bool IsLike(this string s, string s2)
{
int matched = 0;
for (int i = 0; i < s2.Length; i++)
{
if (matched >= s.Length)
return false;
char c = s2[i];
if (c == '?')
matched++;
else if (c == '*')
{
if ((i + 1) < s2.Length)
{
char next = s2[i + 1];
int j = s.IndexOf(next, matched + 1);
if (j < 0)
return false;
matched = j;
}
else break; // '*' matches rest of s
}
else
{
if (c != s[matched])
return false;
matched++;
}
}
return (matched == s.Length);
}
}
You would use it like this:
string s = "12345";
Console.WriteLine(s.IsLike("1*5")); // Returns true
Of course, you could write the same method using regular expressions, which would be shorter and simpler than the one above.
EDIT:
I had a little time to play with this today. I ended up writing an article that presents several ways you can get the functionality of the Like operator from C#. The article is Implementing VB's Like Operator in C#.
There is no Like in C#. Use regular expressions to get the functionality you want.
You might want to start with this intro tutorial: C# Regex.Match
Regex.IsMatch("apple", "*p?e")
for simple pattern matching:
string.Contains()
Related
This question already has answers here:
Can you explain lambda expressions? [duplicate]
(6 answers)
What does the '=>' syntax in C# mean?
(7 answers)
Closed 4 years ago.
I am new to C# and coding in general and have a question on one exercise I'm doing. I am following the exercises on w3resource and I came across a challenge where I have to solve this:
"Write a C# program to check if a given string contains 'w' character between 1 and 3 times."
My solution was this:
var theString = Console.ReadLine();
var theArray = theString.ToCharArray();
int betweenOneAndThree = 0;
for (int i = 0; i < theArray.Length - 1; i++)
{
if (theArray[i] == 'w')
betweenOneAndThree++;
}
Console.WriteLine(betweenOneAndThree >= 1 && betweenOneAndThree <= 3);
Console.ReadLine();
This worked just fine, but I checked their solution and it goes like this:
Console.Write("Input a string (contains at least one 'w' char) : ");
string str = Console.ReadLine();
var count = str.Count(s => s == 'w');
Console.WriteLine("Test the string contains 'w' character between 1 and 3 times: ");
Console.WriteLine(count >= 1 && count <= 3);
Console.ReadLine();
I can't see 's' being declared as a char variable and I do not understand what it does here. Can anyone please explain to me what s => s == 'w' does?
Yes, I have tried googling this. But I can't seem to find an answer.
Thank you in advance :)
This is a lambda expression.
In this case it declares an anonymous delegate which is passed to Count, whose signature for this overload specifies a Func<T, bool> which is a typed representation of an anonymous function which takes a T (the type of the object in the collection) and returns bool. Count() here will execute this function against each object in the collection, and count how many times it returned true.
str.Count(s => s == 'w') is basically a shortened way to say this:
result = 0;
foreach (char s in str)
{
if (s == 'w')
{
result += 1;
}
}
return result;
s => s == 'w' is Predicate delegate with lambda expression,
str.Count(s => s == 'w') simply counts the occurences of the characters w
I'm relatively new to programming, and I'm currently working on a C# string based calculator. A lot of it works fine already, but I'm having problems with negative coefficients. My calculator engine always looks for the next operator and calculates accordingly, so the problem is that if I want to calculate "-5+6", the first operation is "-5", but it obviously can't be calculated. How can I separate operator and coefficient?
What I've come up with so far (small extract of the whole code)
if (nextOperation.Contains("+"))
{
string firstOperationResult = Calculate(nextOperation.Split('+').ToList(), "+")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, firstOperationResult);
return CalculateDashOperation(partialFormulaReplacement);
}
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") > 0)
{
string resultOfFirstOperation = Calculate(nextOperation.Split('-').ToList(), "-")[0];
string partialFormulaReplacement = partialFormula.Replace(nextOperation, resultOfFirstOperation);
return CalculateDashOperation(partialFormulaReplacement);
}
//added
else if (nextOperation.Contains("-") && nextOperation.IndexOf("-") == 0)
{
//what to do
}
//added
return partialFormula;
"-5" can be treated as meaning "0-5", so you could say there's an implicit zero if you see an operand in the first position of the string. Note that this approach will only work for the operators + and -.
As for the problem of attempting to calculate "-5" again, I suggest you use the 0 as an argument to your Calculate function, rather than prepending it to the string you're processing:
Calculate(new List<string>{"0", nextOperation[1]}, "-")
Also, as has been pointed out in the comments, this approach will not cover all possible cases, and if this isn't an academic exercise then there are solutions out there that already solve this problem.
The sample code looks a little short. But let's try to suggest:
nextOperation is a string containing something like "1 * -6 + 6"
In order to evaluate this expression yout have to 'encrypt' your string first.
The topic you are looking for is parenthesis
A nice explanation of the basic (in python) can be found here.
But this question is already answered here.
Use NCalc Library:
Dont reinvent wheel, * and / priorities is already implemented.
Simple expressions
Expression e = new Expression("2 + 3 * 5");
Debug.Assert(17 == e.Evaluate());
Handles mathematical functional from System.Math
Debug.Assert(0 == new Expression("Sin(0)").Evaluate());
Debug.Assert(2 == new Expression("Sqrt(4)").Evaluate());
Debug.Assert(0 == new Expression("Tan(0)").Evaluate());
I am converting code from Java to C#, but having issues figuring out some keyword equivalence. I have looked over the web and can't find anything. Updated added number 3.
1) Does anyone know what C# uses for charAt()? Below is how I am trying to use it.
curr = tokens[i].charAt(0);
2) Also having issues converting isEmpty() to C# syntax.
if (par.isEmpty())
3) How should I convert this:
op2 = compute.pop().intValue();
Thanks!
1) Strings can have their characters accessed by using the [] operator:
curr = (tokens[i])[0];
2) IsEmpty becomes String.IsNullOrEmpty or String.IsNullOrWhiteSpace depending on what you want (the second is only available in .NET 4+ as well).
3) From what research I could find, it looks like intValue deals with boxing/unboxing. If you stick with working with ints, you shouldn't need to worry about that in C#. "Pop" will work the same if you have a Stack collection. Hopefully that gives you enough to convert the line.
1) In C# a string is also an array of characters.So you can access a character using the indexer:
curr = tokens[i][0]
2) You can compare your string with string.Empty or use String.IsNullOrEmpty method to check whether a string is empty or not:
if( par == string.Empty )
OR:
if( string.IsNullOrEmpty(par) );
Assuming tokens[i] is a string, treat the string as an array of characters:
var firstCharacter = tokens[i][0];
Assuming par is also a string, the string.IsNullOrEmpty() method can help you test whether or not a particular string is empty:
if (string.IsNullOrEmpty(par))
{
}
If par is a Stack<String> as you've indicated, then you could test whether it was empty (has no elements) with a simple bit of LINQ:
if (!par.Any())
{
// par has no elements
}
Alternatively, you could use the Count property in the Stack class:
if (par.Count == 0)
{
// par has no elements
}
A different approach:
1) You can use curr = tokens[i].ElementAt(0); This will return the same result as charAt(0)
2) if( string.IsNullOrEmpty(par) ); will do the job.
I want to check if a string contains more than one character in the string?
If i have a string 12121.23.2 so i want to check if it contains more than one . in the string.
You can compare IndexOf to LastIndexOf to check if there is more than one specific character in a string without explicit counting:
var s = "12121.23.2";
var ch = '.';
if (s.IndexOf(ch) != s.LastIndexOf(ch)) {
...
}
You can easily count the number of occurences of a character with LINQ:
string foo = "12121.23.2";
foo.Count(c => c == '.');
If performance matters, write it yourself:
public static bool ContainsDuplicateCharacter(this string s, char c)
{
bool seenFirst = false;
for (int i = 0; i < s.Length; i++)
{
if (s[i] != c)
continue;
if (seenFirst)
return true;
seenFirst = true;
}
return false;
}
In this way, you only make one pass through the string's contents, and you bail out as early as possible. In the worst case you visit all characters only once. In #dasblinkenlight's answer, you would visit all characters twice, and in #mensi's answer, you have to count all instances, even though once you have two you can stop the calculation. Further, using the Count extension method involves using an Enumerable<char> which will run more slowly than directly accessing the characters at specific indices.
Then you may write:
string s = "12121.23.2";
Debug.Assert(s.ContainsDuplicateCharacter('.'));
Debug.Assert(s.ContainsDuplicateCharacter('1'));
Debug.Assert(s.ContainsDuplicateCharacter('2'));
Debug.Assert(!s.ContainsDuplicateCharacter('3'));
Debug.Assert(!s.ContainsDuplicateCharacter('Z'));
I also think it's nicer to have a function that explains exactly what you're trying to achieve. You could wrap any of the other answers in such a function too, however.
Boolean MoreThanOne(String str, Char c)
{
return str.Count(x => x==c) > 1;
}
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C# Regex: Checking for “a-z” and “A-Z”
I could just use the code below:
String hello = "Hello1";
Char[] convertedString = String.ToCharArray();
int errorCounter = 0;
for (int i = 0; i < CreateAccountPage_PasswordBox_Password.Password.Length; i++) {
if (convertedString[i].Equals('a') || convertedString[i].Equals('A') .....
|| convertedString[i].Equals('z') || convertedString[i].Equals('Z')) {
errorCounter++;
}
}
if(errorCounter > 0) {
//do something
}
but I suppose it takes too much line for just a simple purpose, I believe there is a way which is much more simple, the way which I have not yet mastered.
What about:
//true if it doesn't contain letters
bool result = hello.Any(x => !char.IsLetter(x));
Replace your for loop by this :
errorCounter = Regex.Matches(yourstring,#"[a-zA-Z]").Count;
Remember to use Regex class, you have to using System.Text.RegularExpressions; in your import
You could use RegEx:
Regex.IsMatch(hello, #"^[a-zA-Z]+$");
If you don't like that, you can use LINQ:
hello.All(Char.IsLetter);
Or, you can loop through the characters, and use isAlpha:
Char.IsLetter(character);
You can look for regular expression
Regex.IsMatch(str, #"^[a-zA-Z]+$");
For a minimal change:
for(int i=0; i<str.Length; i++ )
if(str[i] >= 'a' && str[i] <= 'z' || str[i] >= 'A' && str[i] <= 'Z')
errorCount++;
You could use regular expressions, at least if speed is not an issue and you do not really need the actual exact count.
Use regular expression
no need to convert it to char array
if(Regex.IsMatch("yourString",".*?[a-zA-Z].*?"))
{
errorCounter++;
}