Issue with infinite loop when reading from file - c#

I am writing a program in C# to read from a file and output to a csv file all of the unique words and the number of occurrences in the file for each word. My issue is when I try to run my program, I never get out of my while loop that goes line by line.
public override List<WordEntry> GetWordCount()
{
List<WordEntry> words = new List<WordEntry>();
WordEntry wordEntry = new WordEntry();
//string[] tokens = null;
string line, temp, getword;
int count = 0, index = 0;
long number;
while ((line = input.ReadLine()) != null)
{
if (line == null)
Debug.Write("shouldnt happen");
char[] delimit = { ' ', ',' };
string[] tokens = line.Split(delimit);
if (words.Count == 0)
{
wordEntry.Word = tokens[0];
wordEntry.WordCount = 1;
words.Add(wordEntry);
}//end if
for (int i = 0; i < tokens.Length; i++)
{
for (int j = 0; j < words.Count; j++)
{
if (tokens[i] == words[j].Word)
{
number = words[j].WordCount;
number++;
getword = words[j].Word;
wordEntry.WordCount = number;
wordEntry.Word = getword;
words.RemoveAt(j);
words.Insert(j, wordEntry);
}//end if
else
{
wordEntry.Word = tokens[i];
wordEntry.WordCount = 1;
words.Add(wordEntry);
}//end else
}//end for
}//end for
}//end while
return words;
}
It is getting stuck in the while loop as if it never reaches the end of the file. The file is 2.6 MB so it should be able to make it to the end.

Here's how you can rewrite your code to use a dictionary.
var words = new Dictionary<string,int>();
while ((line = input.ReadLine()) != null)
{
if (line == null)
Debug.Write("shouldnt happen");
char[] delimit = { ' ', ',' };
string[] tokens = line.Split(delimit);
foreach (var word in tokens)
{
if(words.ContainsKey(word))
words[word]++;
else
words.Add(word, 1);
}
}
This reduces the complexity of the code because dictionary has a O(1) lookup.
EDIT
You can convert the dictionary into List<WordEntry> like this.
return words
.Select(kvp => new WorkEntry
{
Word = kvp.Key,
WordCount = kvp.Value
})
.ToList();

I guess in fact your code doesn't get out of the "for (int j = 0; j < words.Count; j++)" because new items are kept being added to the words list.

Related

Take only letters from the string and reverse them

I'm preparing for my interview, faced the problem with the task. The case is that we're having a string:
test12pop90java989python
I need to return new string where words will be reversed and numbers will stay in the same place:
test12pop90java989python ==> tset12pop90avaj989nohtyp
What I started with:
Transferring string to char array
Use for loop + Char.IsNumber
??
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
....
}
}
but currently I'm stuck and don't know how to proceed, any tips how it can be done?
You can't reverse a run of letters until you've observed the entire run; until then, you need to keep track of the pending letters to be reversed and appended to the final output upon encountering a number or the end of the string. By storing these pending characters in a Stack<> they are naturally returned in the reverse order they were added.
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
Stack<char> pending = new Stack<char>();
foreach (char c in input)
if (char.IsNumber(c))
{
// In the reverse order of which they were added, consume
// and append pending characters as long as they are available
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
// Alternatively...
//foreach (char p in pending)
// outputBuilder.Append(p);
//pending.Clear();
outputBuilder.Append(c);
}
else
pending.Push(c);
// Handle pending characters when input does not end with a number
while (pending.Count > 0)
outputBuilder.Append(pending.Pop());
return outputBuilder.ToString();
}
A similar but buffer-free way is to do it is to store the index of the start of the current run of letters, then walk back through and append each character when a number is found...
static string Transform(string input)
{
StringBuilder outputBuilder = new StringBuilder(input.Length);
int lettersStartIndex = -1;
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (char.IsNumber(c))
{
if (lettersStartIndex >= 0)
{
// Iterate backwards from the previous character to the start of the run
for (int j = i - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
lettersStartIndex = -1;
}
outputBuilder.Append(c);
}
else if (lettersStartIndex < 0)
lettersStartIndex = i;
}
// Handle remaining characters when input does not end with a number
if (lettersStartIndex >= 0)
for (int j = input.Length - 1; j >= lettersStartIndex; j--)
outputBuilder.Append(input[j]);
return outputBuilder.ToString();
}
For both implementations, calling Transform() with...
string[] inputs = new string[] {
"test12pop90java989python",
"123test12pop90java989python321",
"This text contains no numbers",
"1a2b3c"
};
for (int i = 0; i < inputs.Length; i++)
{
string input = inputs[i];
string output = Transform(input);
Console.WriteLine($" Input[{i}]: \"{input }\"");
Console.WriteLine($"Output[{i}]: \"{output}\"");
Console.WriteLine();
}
...produces this output...
Input[0]: "test12pop90java989python"
Output[0]: "tset12pop90avaj989nohtyp"
Input[1]: "123test12pop90java989python321"
Output[1]: "123tset12pop90avaj989nohtyp321"
Input[2]: "This text contains no numbers"
Output[2]: "srebmun on sniatnoc txet sihT"
Input[3]: "1a2b3c"
Output[3]: "1a2b3c"
A possible solution using Regex and Linq:
using System;
using System.Text.RegularExpressions;
using System.Linq;
public class Program
{
public static void Main()
{
var result = "";
var matchList = Regex.Matches("test12pop90java989python", "([a-zA-Z]*)(\\d*)");
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
foreach (var el in list)
{
if (el.All(char.IsDigit))
{
result += el;
}
else
{
result += new string(el.Reverse().ToArray());
}
}
Console.WriteLine(result);
}
}
I've used code from stackoverflow.com/a/21123574/1037948 to create a list of Regex matches on line 11:
var list = matchList.Cast<Match>().SelectMany(o =>o.Groups.Cast<Capture>().Skip(1).Select(c => c.Value));
Hey you can do something like:
string test = "test12pop90java989python", tempStr = "", finalstr = "";
var charArray = test.ToCharArray();
for (int i = 0; i < charArray.Length; i++)
{
if (!Char.IsNumber(charArray[i]))
{
tempStr += charArray[i];
}
else
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
finalstr += charArray[i];
}
}
if(tempStr != "" && tempStr != null)
{
char[] ReverseString = tempStr.Reverse().ToArray();
foreach (char charItem in ReverseString)
{
finalstr += charItem;
}
tempStr = "";
}
I hope this helps

C# Remove An Empty Character Array

I have character arrays seperated into multiple groups, my code uses a character from every group, so once character in a group is processed it will go to the next. I want to remove a group when it's considered empty. (or alternative if you can help fix the code so it skips empty groups)
In the form, there are checkboxes which add the specific characters to their specified group, you have the option to add those characters of choice or not, which I also have a user include input textbox if they want to add their personal characters, but in a case of a char group being empty I get an exception most likely due to the group having no characters.
Exception:
"System.IndexOutOfRangeException: 'Index was outside the bounds of the
array."
For
"result[i] = charGroups[nextGroupIdx][nextCharIdx];"
char[][] charGroups = new char[][]
{
CapitalCharacterSet.ToCharArray(),
LowercaseCharacterSet.ToCharArray(),
NumbersCharacterSet.ToCharArray(),
IncludeCharacterSet.ToCharArray(),
SpecialCharacterSet.ToCharArray()
};
FULL CODE:
char[][] charGroups = new char[][]
{
CapitalCharacterSet.ToCharArray(),
LowercaseCharacterSet.ToCharArray(),
NumbersCharacterSet.ToCharArray(),
IncludeCharacterSet.ToCharArray(),
SpecialCharacterSet.ToCharArray()
};
int[] charsLeftInGroup = new int[charGroups.Length];
for (int i = 0; i < charsLeftInGroup.Length; i++)
charsLeftInGroup[i] = charGroups[i].Length;
int[] leftGroupsOrder = new int[charGroups.Length];
for (int i = 0; i < leftGroupsOrder.Length; i++)
leftGroupsOrder[i] = i;
byte[] randomBytes = new byte[4];
RNGCryptoServiceProvider rng = new();
rng.GetBytes(randomBytes);
int seed = BitConverter.ToInt32(randomBytes, 0);
Random random = new(seed);
char[] result = null;
result = new char[length.Value];
int nextCharIdx;
int nextGroupIdx;
int nextLeftGroupsOrderIdx;
int lastCharIdx;
int lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
for (int i = 0; i < result.Length; i++)
{
if (lastLeftGroupsOrderIdx == 0)
nextLeftGroupsOrderIdx = 0;
else
nextLeftGroupsOrderIdx = random.Next(0, lastLeftGroupsOrderIdx);
nextGroupIdx = leftGroupsOrder[nextLeftGroupsOrderIdx];
lastCharIdx = charsLeftInGroup[nextGroupIdx] - 1;
if (lastCharIdx == 0)
nextCharIdx = 0;
else
nextCharIdx = random.Next(0, lastCharIdx + 1);
try
{
result[i] = charGroups[nextGroupIdx][nextCharIdx];
}
catch
{
if (lastCharIdx == 0)
nextCharIdx = 0;
else
nextCharIdx = random.Next(0, lastCharIdx + 1);
}
if (lastCharIdx == 0)
charsLeftInGroup[nextGroupIdx] = charGroups[nextGroupIdx].Length;
else
{
if (lastCharIdx != nextCharIdx)
{
char temp = charGroups[nextGroupIdx][lastCharIdx];
charGroups[nextGroupIdx][lastCharIdx] =
charGroups[nextGroupIdx][nextCharIdx];
charGroups[nextGroupIdx][nextCharIdx] = temp;
}
charsLeftInGroup[nextGroupIdx]--;
}
if (lastLeftGroupsOrderIdx == 0)
lastLeftGroupsOrderIdx = leftGroupsOrder.Length - 1;
else
if (lastLeftGroupsOrderIdx != nextLeftGroupsOrderIdx)
{
int temp = leftGroupsOrder[lastLeftGroupsOrderIdx];
leftGroupsOrder[lastLeftGroupsOrderIdx] =
leftGroupsOrder[nextLeftGroupsOrderIdx];
leftGroupsOrder[nextLeftGroupsOrderIdx] = temp;
}
lastLeftGroupsOrderIdx--;
}
}

Store String Character in a Jagged Array

I have a string and want to store every word characters in this string in a jagged array without using a split() method, just loops. I tried this code but it didnt work,i want the result will be something like that:
sepwords[0][1] = {H,e,l,l,o};
sepwords[0][2] = {h,o,w};
sepwords[0][3] = {a,r,e};
sepwords[0][4] = {y,o,u};
The code i tried:
for (int i = 0; i < length; i++)
{
letters[i] = text[i];
}
foreach (char item in letters)
{
for (int i = 0; i < length; i++)
{
if (letters[i] != ',' || letters[i] != ';' || letters[i] != '!' || letters[i] != '?' || letters[i] != '.' || letters[i] != ' ')
{
for (int j = 0; j < length; j++)
{
sepwords[0] = new char[length];
sepwords[0][j] = letters[i];
}
}
else
{
continue;
}
}
}
sepwords[0] = new char[length];
You're overwriting every array with a new one when you reach a new word.
You can simply do this..
char[][] sepwords = new char[4][];
sepwords[0] = "Hello".ToCharArray();
sepwords[1] = "how".ToCharArray();
sepwords[2] = "are".ToCharArray();
sepwords[3] = "you".ToCharArray();

Create 2D array from txt file

Okay so I've managed to read in a .txt file... now I'm trying to figure the best way to convert this information into a 2D array.
My text file (first two number provide height and width):
5
5
0,0,0,0,0
0,0,0,0,0
0,0,1,0,0
0,1,1,1,0
1,1,1,1,1
My C# / XNA:
string fileContents = string.Empty;
try
{
using (StreamReader reader = new StreamReader("Content/map.txt"))
{
fileContents = reader.ReadToEnd().ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
Now what I need to do next is define the size of the 2-dimensional map array and then populate the entry values... this is where I'm getting a bit stuck and have found various ways I can loop through the data but I don't think any of them have been terribly tidy.
What I've tried to do is have one loops which splits by newline... and then another loop which splits by comma delimiter.
Is this the best way to do it... or are there better alternatives?
It can be done with LINQ but that is only practical when you want (accept) an array-of-array, int[][] instead of a straight 2-dimensional int[,] .
int[][] data =
File.ReadLines(fileName)
.Skip(2)
.Select(l => l.Split(',').Select(n => int.Parse(n)).ToArray())
.ToArray();
The code below doesn't require the first to rows in your sample .CSV file:
5
5
I'd prefer it this way, but as a consequence, the code below reads the file twice. It would take a small modification use the first two rows in your sample instead.
private int[,] LoadData(string inputFilePath)
{
int[,] data = null;
if (File.Exists(inputFilePath))
{
Dictionary<string, int> counts = GetRowAndColumnCounts(inputFilePath);
int rowCount = counts["row_count"];
int columnCount = counts["column_count"];
data = new int[rowCount, columnCount];
using (StreamReader sr = File.OpenText(inputFilePath))
{
string s = "";
string[] split = null;
for (int i = 0; (s = sr.ReadLine()) != null; i++)
{
split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
for (int j = 0; j < columnCount; j++)
{
data[i, j] = int.Parse(split[j]);
}
}
}
}
else
{
throw new FileDoesNotExistException("Input file does not exist");
}
return data;
}
private Dictionary<string, int> GetRowAndColumnCounts(string inputFilePath)
{
int rowCount = 0;
int columnCount = 0;
if (File.Exists(inputFilePath))
{
using (StreamReader sr = File.OpenText(inputFilePath))
{
string[] split = null;
int lineCount = 0;
for (string s = sr.ReadLine(); s != null; s = sr.ReadLine())
{
split = s.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
if (columnCount == 0)
{
columnCount = split.Length;
}
lineCount++;
}
rowCount = lineCount;
}
if (rowCount == 0 || columnCount == 0)
{
throw new FileEmptyException("No input data");
}
}
else
{
throw new FileDoesNotExistException("Input file does not exist");
}
Dictionary<string, int> counts = new Dictionary<string, int>();
counts.Add("row_count", rowCount);
counts.Add("column_count", columnCount);
return counts;
}
Here's the solution I've come up with which appears to work.
int[,] txtmap;
int height = 0;
int width = 0;
string fileContents = string.Empty;
try
{
using (StreamReader reader = new StreamReader("Content/map.txt"))
{
fileContents = reader.ReadToEnd().ToString();
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
string[] parts = fileContents.Split(new string[] { "\r\n" }, StringSplitOptions.None);
for (int i = 0; i < parts.Length; i++)
{
if (i == 0)
{
// set width
width = Int16.Parse(parts[i]);
}
else if (i == 1)
{
// set height
height = Int16.Parse(parts[i]);
txtmap = new int[width, height];
}
if (i > 1)
{
// loop through tiles and assign them as needed
string[] tiles = parts[i].Split(new string[] { "," }, StringSplitOptions.None);
for (int j = 0; j < tiles.Length; j++)
{
txtmap[i - 2, j] = Int16.Parse(tiles[j]);
}
}
}

Splitting Comma Separated Values (CSV)

How to split the CSV file in c sharp? And how to display this?
I've been using the TextFieldParser Class in the Microsoft.VisualBasic.FileIO namespace for a C# project I'm working on. It will handle complications such as embedded commas or fields that are enclosed in quotes etc. It returns a string[] and, in addition to CSV files, can also be used for parsing just about any type of structured text file.
Display where? About splitting, the best way is to use a good library to that effect.
This library is pretty good, I can recommend it heartily.
The problems using naïve methods is that the usually fail, there are tons of considerations without even thinking about performance:
What if the text contains commas
Support for the many existing formats (separated by semicolon, or text surrounded by quotes, or single quotes, etc.)
and many others
Import Micorosoft.VisualBasic as a reference (I know, its not that bad) and use Microsoft.VisualBasic.FileIO.TextFieldParser - this handles CSV files very well, and can be used in any .Net language.
read the file one line at a time, then ...
foreach (String line in line.Split(new char[] { ',' }))
Console.WriteLine(line);
This is a CSV parser I use on occasion.
Usage: (dgvMyView is a datagrid type.)
CSVReader reader = new CSVReader("C:\MyFile.txt");
reader.DisplayResults(dgvMyView);
Class:
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
public class CSVReader
{
private const string ESCAPE_SPLIT_REGEX = "({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*";
private string[] FieldNames;
private List<string[]> Records;
private int ReadIndex;
public CSVReader(string File)
{
Records = new List<string[]>();
string[] Record = null;
StreamReader Reader = new StreamReader(File);
int Index = 0;
bool BlankRecord = true;
FieldNames = GetEscapedSVs(Reader.ReadLine());
while (!Reader.EndOfStream)
{
Record = GetEscapedSVs(Reader.ReadLine());
BlankRecord = true;
for (Index = 0; Index <= Record.Length - 1; Index++)
{
if (!string.IsNullOrEmpty(Record[Index])) BlankRecord = false;
}
if (!BlankRecord) Records.Add(Record);
}
ReadIndex = -1;
Reader.Close();
}
private string[] GetEscapedSVs(string Data)
{
return GetEscapedSVs(Data, ",", "\"");
}
private string[] GetEscapedSVs(string Data, string Separator, string Escape)
{
string[] Result = null;
int Index = 0;
int PriorMatchIndex = 0;
MatchCollection Matches = Regex.Matches(Data, string.Format(ESCAPE_SPLIT_REGEX, Separator, Escape));
Result = new string[Matches.Count];
for (Index = 0; Index <= Result.Length - 2; Index++)
{
Result[Index] = Data.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
Result[Result.Length - 1] = Data.Substring(PriorMatchIndex);
for (Index = 0; Index <= Result.Length - 1; Index++)
{
if (Regex.IsMatch(Result[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) Result[Index] = Result[Index].Substring(1, Result[Index].Length - 2);
Result[Index] = Result[Index].Replace(Escape + Escape, Escape);
if (Result[Index] == null) Result[Index] = "";
}
return Result;
}
public int FieldCount
{
get { return FieldNames.Length; }
}
public string GetString(int Index)
{
return Records[ReadIndex][Index];
}
public string GetName(int Index)
{
return FieldNames[Index];
}
public bool Read()
{
ReadIndex = ReadIndex + 1;
return ReadIndex < Records.Count;
}
public void DisplayResults(DataGridView DataView)
{
DataGridViewColumn col = default(DataGridViewColumn);
DataGridViewRow row = default(DataGridViewRow);
DataGridViewCell cell = default(DataGridViewCell);
DataGridViewColumnHeaderCell header = default(DataGridViewColumnHeaderCell);
int Index = 0;
ReadIndex = -1;
DataView.Rows.Clear();
DataView.Columns.Clear();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
col = new DataGridViewColumn();
col.CellTemplate = new DataGridViewTextBoxCell();
header = new DataGridViewColumnHeaderCell();
header.Value = GetName(Index);
col.HeaderCell = header;
DataView.Columns.Add(col);
}
while (Read())
{
row = new DataGridViewRow();
for (Index = 0; Index <= FieldCount - 1; Index++)
{
cell = new DataGridViewTextBoxCell();
cell.Value = GetString(Index).ToString();
row.Cells.Add(cell);
}
DataView.Rows.Add(row);
}
}
}
I had got the result for my query. its like simple like i had read a file using io.file. and all the text are stored into a string. After that i splitted with a seperator. The code is shown below.
using System;
using System.Collections.Generic;
using System.Text;
namespace CSV
{
class Program
{
static void Main(string[] args)
{
string csv = "user1, user2, user3,user4,user5";
string[] split = csv.Split(new char[] {',',' '});
foreach(string s in split)
{
if (s.Trim() != "")
Console.WriteLine(s);
}
Console.ReadLine();
}
}
}
The following function takes a line from a CSV file and splits it into a List<string>.
Arguments:
string line = the line to split
string textQualifier = what (if any) text qualifier (i.e. "" or "\"" or "'")
char delim = the field delimiter (i.e. ',' or ';' or '|' or '\t')
int colCount = the expected number of fields (0 means don't check)
Example usage:
List<string> fields = SplitLine(line, "\"", ',', 5);
// or
List<string> fields = SplitLine(line, "'", '|', 10);
// or
List<string> fields = SplitLine(line, "", '\t', 0);
Function:
private List<string> SplitLine(string line, string textQualifier, char delim, int colCount)
{
List<string> fields = new List<string>();
string origLine = line;
char textQual = '"';
bool hasTextQual = false;
if (!String.IsNullOrEmpty(textQualifier))
{
hasTextQual = true;
textQual = textQualifier[0];
}
if (hasTextQual)
{
while (!String.IsNullOrEmpty(line))
{
if (line[0] == textQual) // field is text qualified so look for next unqualified delimiter
{
int fieldLen = 1;
while (true)
{
if (line.Length == 2) // must be final field (zero length)
{
fieldLen = 2;
break;
}
else if (fieldLen + 1 >= line.Length) // must be final field
{
fieldLen += 1;
break;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == textQual) // escaped text qualifier
{
fieldLen += 2;
}
else if (line[fieldLen] == textQual && line[fieldLen + 1] == delim) // must be end of field
{
fieldLen += 1;
break;
}
else // not a delimiter
{
fieldLen += 1;
}
}
string escapedQual = textQual.ToString() + textQual.ToString();
fields.Add(line.Substring(1, fieldLen - 2).Replace(escapedQual, textQual.ToString())); // replace escaped qualifiers
if (line.Length >= fieldLen + 1)
{
line = line.Substring(fieldLen + 1);
if (line == "") // blank final field
{
fields.Add("");
}
}
else
{
line = "";
}
}
else // field is not text qualified
{
int fieldLen = line.IndexOf(delim);
if (fieldLen != -1) // check next delimiter position
{
fields.Add(line.Substring(0, fieldLen));
line = line.Substring(fieldLen + 1);
if (line == "") // final field must be blank
{
fields.Add("");
}
}
else // must be last field
{
fields.Add(line);
line = "";
}
}
}
}
else // if there is no text qualifier, then use existing split function
{
fields.AddRange(line.Split(delim));
}
if (colCount > 0 && colCount != fields.Count) // count doesn't match expected so throw exception
{
throw new Exception("Field count was:" + fields.Count.ToString() + ", expected:" + colCount.ToString() + ". Line:" + origLine);
}
return fields;
}
Problem: Convert a comma separated string into an array where commas in "quoted strings,,," should not be considered as separators but as part of an entry
Input:
String: First,"Second","Even,With,Commas",,Normal,"Sentence,with ""different"" problems",3,4,5
Output:
String-Array: ['First','Second','Even,With,Commas','','Normal','Sentence,with "different" problems','3','4','5']
Code:
string sLine;
sLine = "First,\"Second\",\"Even,With,Commas\",,Normal,\"Sentence,with \"\"different\"\" problems\",3,4,5";
// 1. Split line by separator; do not split if separator is within quotes
string Separator = ",";
string Escape = '"'.ToString();
MatchCollection Matches = Regex.Matches(sLine,
string.Format("({1}[^{1}]*{1})*(?<Separator>{0})({1}[^{1}]*{1})*", Separator, Escape));
string[] asColumns = new string[Matches.Count + 1];
int PriorMatchIndex = 0;
for (int Index = 0; Index <= asColumns.Length - 2; Index++)
{
asColumns[Index] = sLine.Substring(PriorMatchIndex, Matches[Index].Groups["Separator"].Index - PriorMatchIndex);
PriorMatchIndex = Matches[Index].Groups["Separator"].Index + Separator.Length;
}
asColumns[asColumns.Length - 1] = sLine.Substring(PriorMatchIndex);
// 2. Remove quotes
for (int Index = 0; Index <= asColumns.Length - 1; Index++)
{
if (Regex.IsMatch(asColumns[Index], string.Format("^{0}[^{0}].*[^{0}]{0}$", Escape))) // If "Text" is sourrounded by quotes (but ignore double quotes => "Leave ""inside"" quotes")
{
asColumns[Index] = asColumns[Index].Substring(1, asColumns[Index].Length - 2); // "Text" => Text
}
asColumns[Index] = asColumns[Index].Replace(Escape + Escape, Escape); // Remove double quotes ('My ""special"" text' => 'My "special" text')
if (asColumns[Index] == null) asColumns[Index] = "";
}
The output array is asColumns

Categories