Foreach loop using Regex to find XML pattern - c#

I've created a regex pattern which finds all #REF in my excel file. I've created a foreach loop to return all the #REF and siplay them in the console along with a count of them. This works fine. However I then created a foreach loop to remove all the #REF references but it only removes one each time I run the project. I've debugged this and after Regex finds the match once in the if statement the next time it enters into the foreach it skips the if statement as if it can't find another match. I'm not sure why this is
My code is as fallows
Code to return all the #ref values
using (var spreadsheet = DocumentFormat.OpenXml.Packaging.SpreadsheetDocument.Open(#"C:\Users\Craig\Desktop\newTest.xlsx", true))
{
var workbook = spreadsheet.WorkbookPart;
Workbook w = new Workbook();
var names = workbook.Workbook.DefinedNames;
var work = workbook.Workbook;
System.Text.RegularExpressions.Regex regex = new System.Text.RegularExpressions.Regex(#"#REF");
int count = result.InactiveNamedRangeCount = names.Count(n => regex.IsMatch(n.InnerText));
Console.WriteLine(count);
foreach (var name in names)
{
if (regex.IsMatch(name.InnerText))
{
Console.WriteLine(name.InnerText);
}
}
Code to delete each #REF value
foreach (var name in names)
{
if (regex.IsMatch(name.InnerText))
{
name.Remove();
work.Save();
}
}
Console.WriteLine(count);
Console.ReadKey();
}

The solution to the problem was I needed to add a ToList to my names variable.
foreach (var name in names.ToList())
{
if (regex.IsMatch(name.InnerText))
{
name.Remove();
work.Save();
}
}

Related

How to check and insert values to list C#

After accessing the local file, I need to check and add the missing column (walmart) before converting it to xml. I confirm data is available in the csv file.
Currently I am getting an error
System.InvalidOperationException: 'Collection was modified; enumeration operation may not execute
Code:
string[] vs = File.ReadAllLines(#"C:/Users/Raw.csv");
var lines = new List <String>();
lines = vs.ToList();
foreach (var check in lines)
{
if (!check.Contains("Walmart"))
{
lines.Insert(0,"Walmart");
}
}
foreach (var shw in lines)
{
Console.WriteLine(shw);
}
Techically, if you want just amend your current code you can count how many Walmarts we should add:
var lines = File
.ReadLines(#"C:/Users/Raw.csv")
.ToList();
int walmartsToAdd = 0;
foreach (var check in lines)
if (!check.Contains("Walmart"))
walmartsToAdd += 1;
if (walmartsToAdd > 0)
lines.InsertRange(0, Enumerable.Repeat("Walmart", walmartsToAdd));
foreach (var shw in lines)
Console.WriteLine(shw);
But it seems, that you should modify lines: abc,def => Walmart,abc,def. If it's your case you can just add Select
var lines = File
.ReadLines(#"C:/Users/Raw.csv")
.Select(line => line.StartsWith("Walmart,") ? line : $"Walmart,{line}")
.ToList();
foreach (var shw in lines)
Console.WriteLine(shw);
You can't modify the source Enumerable while iterating on it. I always imagine that the enumerator has inside a current index and if for example, the change would delete all the members the index wouldn't make any sense anymore. The easy solution is to iterate on something else / make a copy.
Here instead of lines you can try iterating on the variable 'vs'.
var vs = File.ReadAllLines(#"C:/Users/Raw.csv");
var lines = vs.ToList();
foreach (var check in vs)
{
if (!check.Contains("Walmart"))
{
lines.Insert(0, "Walmart");
}
}
foreach (var shw in lines)
{
Console.WriteLine(shw);
}

Get all class name icon from fontawesome

I'd like to get all class name icon from fontawesome to list or array in c# from fontawesome.
I'd like to get all variants icon for example:
fas fa-abacus
far fa-abacus
fal fa-abacus
...
I tried to extract it from the css file, but it only gets the icon names themselves without prefixes.
var text = File.ReadAllText(#"fontawesome\all.css");
var allMatches = Regex.Matches(text, #"^\.fa\-(.*):", RegexOptions.Multiline);
Thank's for help.
Monika
public List<string> ListOfFontAwesomeIcons(string FilePath)
{
List<string> response = new List<string>();
List<string> fontAwesomePrefixes = new { "fas", "far" /*manually add all prefixes*/ }
var textLines = File.ReadAllLines($"{FilePath}");
foreach(string l in textLines)
{
foreach(string p in fontAwesomePrefixes)
{
if(l.Contains(p))
response.Add(l.Replace($"{p} "));
}
}
return response;
}
I ran this in C# 9, VS2019 just based off of feeding it a test string, and it worked for me. I double-checked for fa- in the result list to make sure I excluded all of the other results.
Also, I just converted to List of strings for display. You don't really need to do that, depending on what you're doing with your results.
EDIT: Code updated to reflect FA's .css file available on their website, not the format of the string I was using earlier.
Replace the path in the first line with whatever reflects your project. Note that there are faster methods than ReadAllText, but it should be fine for this.
string text = System.IO.File.ReadAllText("./wwwroot/css/all.css");
var allMatches = Regex.Matches(text, "(?<=[.]).*?(fa-)?.*?(?=[:])", RegexOptions.None);
List<string> allMatchesStrings = new();
foreach (var item in allMatches)
{
if (item.ToString().Contains("fa-"))
allMatchesStrings.Add(item.ToString());
}
foreach (var item in allMatchesStrings)
{
Console.WriteLine(item);
}

How can I iterate over an excel file

How can I iterate over an excel file?
I currently have a class using ExcelDataReader
Class => https://paste.lamlam.io/nomehogupi.cs#14fXzlopygZ27adDcXEDtQHT0tWTxoYR
I have a excel file with 5 columns
This is my current code, but it is not exporting the result that I expect ...
TextWriter stream = new StreamWriter("excel Path");
//foreach string in List<string>
foreach(var item in ComboList) {
var rows = ExcelHelper.CellValueCollection(item.Key);
foreach(var row in rows) {
stream.WriteLine(item.Key + "|" + row);
break;
}
}
stream.Close();
My result:
Column1|Row1
Column1|Row2
Column1|Row3
...
Column2|Row1
Column2|Row2
Column2|Row3
...
Expected:
Column1|Row1|Column2|Row1...
Column1|Row2|Column2|Row2...
Column1|Row3|Column2|Row3...
Thanks
This is the answer, I just needed to get the dataSet and iterate over it, very easy
var data = ExcelHelper.DataSet();
foreach (DataRow dr in data.Tables[0].Rows)
{
Console.WriteLine(dr["Column1"] + "|" + dr["Column2"]);
}
If I understand what you want truly! I think you need to add a method like RowValueCollection to your ExcelHelper as below:
public static IEnumerable<string[]> RowValueCollection()
{
var result = Data.Tables[0].Rows.OfType<DataRow>()
.Select(dr => dr.ItemArray.Select(ia => ia.ToString()).ToArray());
return result;
}
And then use it like this:
var rowValues = ExcelHelper.RowValueCollection();
foreach (var row in rowValues)
{
stream.WriteLine(string.Join("|", row));
}
HTH ;)
The first problem is that you are asking to write two items and only two items on a single line.
Would it help if you made the stream.writeline() statement into a .write() statement and then, after the inner loop performed a .writeline() which would terminate the line?
Apologies for not commenting but not enough Respect points to do so.
- Malc

How to make .Contains() search for the texted typed in a textbox anywhere in the field C#

In the code below, .Contains() only return string that start with the text I type in the TextBox. I want it to return all records that contain that string anywhere in the the searched field. Please advise how I can get Contains() to return the value, alternate ways are welcome as well
Thanks
using (var GC = new GroundCommanderEntities())
{
foreach (var Current in GC.IMF_Extensions.Where(filter => filter.Description.Contains(Search_txt.Text) ))
{
string sss = Current.Description;
Coll.Add(sss);
}
// tried same result foreach (var Current in GC.IMF_Extensions.Where(filter => filter.Description.Contains(Search_txt.Text.Trim()) || filter.Description.StartsWith(Search_txt.Text) || filter.Description.EndsWith(Search_txt.Text)))
// tried same result foreach (var Current in GC.IMF_Extensions.Where(filter => filter.Description.Contains(Search_txt.Text.Trim()) ))
}
Try a simpler method without Linq:
using (var GC = new GroundCommanderEntities())
{
foreach (var Current in GC.IMF_Extensions)
{
if (Current.Description.Contains(Search_txt.Text))
{
Coll.Add(Current.Description);
}
}
}
Try to use ToLower for both strings before Contains. It should be work.
using (var GC = new GroundCommanderEntities())
{
foreach (var Current in GC.IMF_Extensions.Where(filter => filter.Description.ToLower().Contains(Search_txt.Text.ToLower())))
{
Coll.Add(Current.Description);
}
}

C# - Problem removing items in List1 & List2 from List3

I have a file that I am reading in, splitting up into different lists and outputting them into RichTextBox to then be read into 3 different Listboxes. I am currently doing all of this, however I have come across something I do not know how to fix/work around.
My code is below and I seem to be having trouble understanding why it fails to properly work when it gets to the Match twoRegex = Regex.Match(...) section of the code.
CODE:
private void SortDataLines()
{
try
{
// Reads the lines in the file to format.
var fileReader = File.OpenText(openGCFile.FileName);
// Creates a list for the lines to be stored in.
var placementUserDefinedList = new List<string>();
// Reads the first line and does nothing with it.
fileReader.ReadLine();
// Adds each line in the file to the list.
while (true)
{
var line = fileReader.ReadLine();
if (line == null)
break;
placementUserDefinedList.Add(line);
}
// Creates new lists to hold certain matches for each list.
var oneResult = new List<string>();
var twoResult = new List<string>();
var mainResult = new List<string>();
foreach (var userLine in placementUserDefinedList)
mainResult.Add(string.Join(" ", userLine));
foreach (var oneLine in mainResult)
{
// PLACEMENT ONE Regex
Match oneRegex = Regex.Match(oneLine, #"^.+(RES|0402|0201|0603|0805|1206|1306|1608|3216|2551"
+ #"|1913|1313|2513|5125|2525|5619|3813|1508|6431|2512|1505|2208|1005|1010|2010|0505|0705"
+ #"|1020|1812|2225|5764|4532|1210|0816|0363|SOT)");
if (oneRegex.Success)
oneResult.Add(string.Join(" ", oneLine));
}
//
// THIS IS THE SECTION THAT FAILS..
//
foreach(var twoLine in mainResult)
{
//PLACEMENT TWO Regex
Match twoRegex = Regex.Match(twoLine, #"^.+(BGA|SOP8|QSOP|TQSOP|SOIC16|SOIC12|SOIC8|SO8|SO08"
+ #"CQFP|LCC|LGA|OSCCC|PLCC|QFN|QFP|SOJ|SON");
if (twoRegex.Success)
twoResult.Add(string.Join(" ", twoLine));
}
// Removes the matched values from both of the Regex used above.
List<string> userResult = mainResult.Except(oneResult).ToList();
userResult = userResult.Except(twoResult).ToList();
// Prints the proper values into the assigned RichTextBoxes.
foreach (var line in userResult)
userDefinedRichTextBox.AppendText(line + "\n");
foreach (var line in oneResult)
placementOneRichTextBox.AppendText(line + "\n");
foreach (var line in twoResult)
placementTwoRichTextBox.AppendText(line + "\n");
}
// Catches an exception if the file was not opened.
catch (Exception)
{
MessageBox.Show("Could not match any regex values.", "Regular Expression Match Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
QUESTIONS:
Does anyone understand why I am unable to to find, or fail at, the second set of REGEX?
With that, is there a way to fix it?
Suggestions please! :)
Haven't you missed the pipeline character in your second regex between two lines?
Match twoRegex = Regex.Match(twoLine, #"^.+(BGA|SOP8|QSOP|TQSOP|SOIC16|SOIC12|SOIC8|SO8|SO08"
+ #"|CQFP|LCC|LGA|OSCCC|PLCC|QFN|QFP|SOJ|SON)");

Categories

Resources