Comparing multiple strings to list of regular expressions C# - c#

I am trying to compare multiple strings to a list of regular expressions. I am trying to make it so i can compare all the strings i have to all of the regular expressions and if it DOESNT match any of the regular expressions then it gets put into a list so i know it doesnt match. My method works when i have only 1 regular expression but does completely quits working when i add 2 or more.
public List<string> CheckNames(List<string> nameList, List<string> regexList)
{
var missMatchNameList = new List<string>();
foreach (var name in nameList)
{
foreach(var regex in regexList)
{
if (!Regex.IsMatch(name, regex))
{
missMatchNameList.Add(name);
break;
}
}
}
return missMatchNameList;
}
that is my code so far, what am i missing here?? Any tips would be great!

Change this
foreach (var name in nameList)
{
foreach(var regex in regexList)
{
if (!Regex.IsMatch(name, regex))
{
missMatchNameList.Add(name);
break;
}
}
}
To
foreach (var name in nameList)
{
bool match = false;
foreach(var regex in regexList)
{
if (Regex.IsMatch(name, regex))
{
match = true;
break;
}
}
if (!match)
missMatchNameList.Add(name);
}
Your problem was that as soon one of you regex expressions didn't match, it got added to the list, even if it matched another regex.
Also, by keeping the break; you don't carry on processing all the other regexs after you find a match.

Try this one
public List<string> CheckNames(List<string> nameList, List<string> regexList)
{
var missMatchNameList = new List<string>();
foreach (var name in nameList)
{
var matched = false;
foreach(var regex in regexList)
{
if (Regex.IsMatch(name, regex))
{
matched=true;
break;
}
}
if (!matched)
{
missMatchNameList.Add(name);
}
}
return missMatchNameList;
}
this issue because you break when not matching with first regex so you don't compare the remaining regexs

Related

Check if List<string> exists

This is my code
List<string> list = new List<string>() { "bfd", "jy", "aaaaa", "ndnk", "ntfn", "gfm", "gfm", "mhgd5h", "srsr", "ntr", "mtmyt", "dmy", "mmy6", "ngn9d", "y6m1", "d8dm", "bbbbb", "tym", "dmj", "trsh", "tsr"};
List<string> test = new List<string>() {"aaaaa","bbbbb","ccccc","ddddd","eeeee","fffff","ggggg" };
foreach (var a in list)
{
foreach (var i in test)
{
if (i.StartsWith(a) == false)
{
Console.WriteLine(i);
}
}
}
I want to output from the list and match in the test. If the test exists, then it will not be displayed. If there is no side output,But there may be a problem with my code, it will output the same value many times
The list contains aaaaa, according to logic, aaaaa should not be output
Try this:
List<string> list = new List<string>(){"bfd", "jy", "aaaaa", "ndnk", "ntfn", "gfm", "gfm", "mhgd5h", "srsr", "ntr", "mtmyt", "dmy", "mmy6", "ngn9d", "y6m1", "d8dm", "bbbbb", "tym", "dmj", "trsh", "tsr"};
List<string> test = new List<string>(){"aaaaa", "bbbbb", "ccccc", "ddddd", "eeeee", "fffff", "ggggg"};
foreach (var a in list)
{
if (!test.Contains(a))
{
Console.WriteLine(a);
}
}
There are simple solutions using LINQ. But since I assume this is an exercise, I will show you the detailed version using loops.
The problem is that the WriteLine is inside the inner loop. Therefore you will get many repetitions. Store the outcome of the test in a Boolean variable and place the display part after the inner loop.
foreach (var a in list)
{
bool found = false;
foreach (var i in test)
{
if (i.StartsWith(a))
{
found = true;
break; // Exit the inner loop
}
}
if (!found)
{
Console.WriteLine(a); // We must output a here since i out of scope.
}
}
Also, if you want to know whether a specific string is contained in the list, you should probably replace i.StartsWith(a) with i == a.
The code becomes easier to read, if you extract the list search into its own method
private bool IsInList(List<string> list, string item)
{
foreach (string s in list)
{
if (s == item)
{
return true;
}
}
return false;
}
Now, you don't need the Boolean variable any more
foreach (var a in list)
{
if (!IsInList(test, a))
{
Console.WriteLine(a);
}
}
I used !condition (pronounce: "not condition") instead of condition == false. It's terser.
I assume that this is an exercise. In production code you would simply use the built in method Contains of the list.
foreach (var a in list)
{
if (!test.Contains(a))
{
Console.WriteLine(a);
}
}
or even (as #mjwills suggests in his comment):
foreach (var a in list.Except(test)) {
Console.WriteLine(a);
}

Is there a way to combine foreach loop

I have 2 lists as follows:
valuesToMatch = ["someemail#something.com", "123-45-6789"]
regexValuesToMatchWith = ["^[a-zA-Z0-9._%+-]+#[a-z0-9-]+\.(com|org|edu|)(\.[a-z]{2,3})?", "^\d{3}-\d{2}-\d{4}$"]
I want to match the email with email regex and SSN number with SSN regex. If both are true, then only I can add data, not otherwise.
public bool MatchRegex(Data data)
{
var regexMatch = false;
var valuesToMatch = GetValuesToMatch(data.values);
var regexValuesToMatchWith = service.Validations(data.id);
foreach (var toMatch in valuesToMatch)
{
foreach (var withRegex in regexValuesToMatchWith)
{
var r = new Regex(withRegex, RegexOptions.IgnoreCase);
if (r.IsMatch(toMatch))
{
regexMatch = true;
}
}
}
if (regexMatch)
{
return dbContext.Add(data);
}
return false;
}
I have looked at approaches online but I am not sure if this is possible to achieve.
Maybe a for loop would be more suitable for what you're trying to achieve.
bool regexMatch = true;
for (int i = 0; i < withRegex.Length; i++)
{
var r = new Regex(valuesToMatch[i], RegexOptions.IgnoreCase);
if (!r.IsMatch(regexValuesToMatchWith[i]))
{
regexMatch = false;
break;
}
}
}
The foreach loop will compare each value with both email and SSN regex, which is unnecessary. Besides that, if you set regexMatch to true like you're doing, it's going to be true even if one of the comparisons doesn't match.
I'm assuming valuesToMatch and regexValuesToMatchWith are always of the same size and with data in correct order, based on your example.

Using lambda expression to select array element where it matches in string

I am trying to select an element in array, that matches something in a string.
For example:
string[] splitChar = new string[] { "+=", "-=" };
string content = "5+=2";
So i want to check if content, contains something from splitChar, and if it does then select the value so it can be assigned to a string variable.
Lambdas and LINQ would be overkill for this. You can just do a simple foreach:
string match = "";
foreach (var str in splitChar)
{
if (content.Contains(str))
{
match = str;
break;
}
}
if (!String.IsNullOrEmpty(match))
{
// Do whatever with `match`
}
If you really wanted to use LINQ, though, FirstOrDefault would be your best bet:
string match = splitChar.FirstOrDefault(s => content.Contains(s));
if (!String.IsNullOrEmpty(match))
{
// Do whatever with `match`
}
Have you tried checking with FirstOrDefault like the following?
string[] splitChar = new string[] { "+=", "-=" };
string content = "5+=2";
var stringPresent = splitChar.FirstOrDefault(x=>content.Contains(x));
if(String.IsNullOrEmpty(stringPresent))
Console.WriteLine("Not found");
else
Console.WriteLine(stringPresent);
Check this Example

Find two strings in list with a regular expression

I need to find two strings within a list that contains the characters from another string, which are not in order. To make it clear, an example could be a list of animals like:
lion
dog
bear
cat
And a given string is: oodilgn.
The answer here would be: lion and dog
Each character from the string will be used only once.
Is there a regular expression that will allow me to do this?
You could try to put the given string between []. These brackets will allow choosing - in any order - from these letters only. This may not be a perfect solution, but it will catch the majority of your list.
For example, you could write oodilgn as [oodilgn], then add a minimum number of letters to be found - let's say 3 - by using the curly brackets {}. The full regex will be like this:
[oodilgn]{3,}
This code basically says: find any word that has three of the letters that are located between brackets in any order.
Demo: https://regex101.com/r/MCWHjQ/2
Here is some example algorithm that does the job. I have assumed that the two strings together don't need to take all letters from the text else i make additional commented check. Also i return first two appropriate answers.
Here is how you call it in the outside function, Main or else:
static void Main(string[] args)
{
var text = "oodilgn";
var listOfWords = new List<string> { "lion", "dog", "bear", "cat" };
ExtractWordsWithSameLetters(text, listOfWords);
}
Here is the function with the algorithm. All string manuplations are entirely with regex.
public static void ExtractWordsWithSameLetters(string text, List<string> listOfWords)
{
string firstWord = null;
string secondWord = null;
for (var i = 0; i < listOfWords.Count - 1; i++)
{
var textCopy = text;
var firstWordIsMatched = true;
foreach (var letter in listOfWords[i])
{
var pattern = $"(.*?)({letter})(.*?)";
var regex = new Regex(pattern);
if (regex.IsMatch(text))
{
textCopy = regex.Replace(textCopy, "$1*$3", 1);
}
else
{
firstWordIsMatched = false;
break;
}
}
if (!firstWordIsMatched)
{
continue;
}
firstWord = listOfWords[i];
for (var j = i + 1; j < listOfWords.Count; j++)
{
var secondWordIsMatched = true;
foreach (var letter in listOfWords[j])
{
var pattern = $"(.*?)({letter})(.*?)";
var regex = new Regex(pattern);
if (regex.IsMatch(text))
{
textCopy = regex.Replace(textCopy, "$1*$3", 1);
}
else
{
secondWordIsMatched = false;
break;
}
}
if (secondWordIsMatched)
{
secondWord = listOfWords[j];
break;
}
}
if (secondWord == null)
{
firstWord = null;
}
else
{
//if (textCopy.ToCharArray().Any(l => l != '*'))
//{
// break;
//}
break;
}
}
if (firstWord != null)
{
Console.WriteLine($"{firstWord} { secondWord}");
}
}
Function is far from optimised but does what you want. If you want to return results, not print them just create an array and stuff firstWord and secondWord in it and have return type string[] or add two paramaters with ref out In those cases you will need to check the result in the calling function.
please try this out
Regex r=new Regex("^[.*oodilgn]$");
var list=new List<String>(){"lion","dog","fish","god"};
var output=list.Where(x=>r.IsMatch(x));
result
output=["lion","dog","god"];

convert foreach loop to linq code

the below code is working as expected but I'm looking to convert the below code to use Linq?
any suggestions?
string[] selections = "Men,Women,Boys".Split(',');
int _chkboxId = 0;
int _chkboxTextId = 1;
try
{
string id = "lstchk_" + _chkboxId;
while (!driver.FindElement(By.Id(id)).Equals(null))
{
string checkboxId = String.Format("lstchk{0}", _chkboxTextId);
string checkboxName = driver.FindElement(By.Id(checkboxId)).Text;
foreach (string match in selections)
{
if (checkboxName == match.Trim())
{
//matched... do more work here...
}
}
}
foreach (string match in selections.Where(match => checkboxName == match.Trim()))
{
//matched... do more work here...
}
If your selections list contains only distinct values, than you could use
if(selections.Any(match=>match.Trim().Equals(checkboxName)))
{
//Do work
}
instead of your loop. Same if your list may contain non-distinct values, but the work should be done only once for each checkboxName
switch(checkboxName) {
case "Men":
case "Women":
case "Boys":
// do more work here
default:
// no match, bail
}
Sometimes, there's just a different way to write the code.
How would you convert this simple foreach to a linq statement?
public List<string> GetItems()
{
var items = new List<string>();
foreach (Ranorex.ListItem item in ranorexComboBox.Items)
{
items.Add(item.Text);
}
return items;
}

Categories