Regex Replace 2 values in C# - c#

If I have a RichTextBox_1 that look like this:
TEXT TEXT 444.444 555.555 270
TEXT TEXT 444.444 555.555 270
TEXT TEXT 444.444 555.555 270
And I would like to replace the values in the third column with values in a RichTextBox_2:
123.456
12.345
-123.987
And the values in the fourth column with values in a RichTextBox_3:
-9.876
98.76
-987.654
To get a final file:
TEXT TEXT 123.456 9.876 270
TEXT TEXT 12.345 98.76 270
TEXT TEXT -123.987 -987.654 270
How could I do this using REGEX?
EDIT:
CODE:
(Splits the values from a ListBox into: RichTextBox_2 and RichTextBox_3. Instead of the ListBox I have moved everything in this to a RichTextBox_1)
private void calculateXAndYPlacement()
{
// Reads the lines in the file to format.
var fileReader = File.OpenText(filePath + "\\Calculating X,Y File.txt");
// Creates a list for the lines to be stored in.
var fileList = new List<string>();
// Adds each line in the file to the list.
var fileLines = ""; #UPDATED #Corey Ogburn
while ((fileLines = fileReader.ReadLine()) != null) #UPDATED #Corey Ogburn
fileList.Add(fileLines); #UPDATED #Corey Ogburn
// Creates new lists to hold certain matches for each list.
var xyResult = new List<string>();
var xResult = new List<string>();
var yResult = new List<string>();
// Iterate over each line in the file and extract the x and y values
fileList.ForEach(line =>
{
Match xyMatch = Regex.Match(line, #"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)");
if (xyMatch.Success)
{
// Grab the x and y values from the regular expression match
String xValue = xyMatch.Groups["x"].Value;
String yValue = xyMatch.Groups["y"].Value;
// Add these two values, separated by a space, to the "xyResult" list.
xyResult.Add(String.Join(" ", new[]{ xValue, yValue }));
// Add the results to the lists.
xResult.Add(xValue);
yResult.Add(yValue);
// Calculate the X & Y values (including the x & y displacements)
double doubleX = double.Parse(xValue);
double doubleXValue = double.Parse(xDisplacementTextBox.Text);
StringBuilder sbX = new StringBuilder();
sbX.AppendLine((doubleX + doubleXValue).ToString());
double doubleY = double.Parse(yValue);
double doubleYValue = double.Parse(yDisplacementTextBox.Text);
StringBuilder sbY = new StringBuilder();
sbY.AppendLine((doubleY + doubleYValue).ToString());
calculatedXRichTextBox.AppendText(sbX + "\n");
calculatedYRichTextBox.AppendText(sbY + "\n");
}
});
}
I was trying to mess around with the Regex.Replace but I am having some trouble... Here is what I what trying and it does not work:
var combinedStringBuilders = new List<string>();
combinedStringBuilders.Add(String.Concat(sbX + "\t" + sbY));
var someNew = Regex.Replace(line, #"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)", combinedStringBuilders);

General non-language specific method.
(I haven't done enough c# to write specific's)
5 (only) columns should be validated first.
This can be done by alternating non-whitespace
then whitespace.
regex: ^(\s*\S+\s+\S+\s+)(\S+)(\s+)(\S+)(\s+\S+\s*)$
replacemnt: ${1}${sbX}${3}${sbY}${5}
Open the 3 files. In a while loop, read a line from each file.
Validate both sbX/sbY that they have no whitespace.
Do the replacement, append the modified line to a file.

You should simply split your string into lines and then columns, I'm guessing your text has msdos line endings (cr+lf).
public string ReplaceColumn( string text, int col, List<string> newValues ){
var sb = new StringBuilder();
var lines = Regex.Split( text, "[\r\n]+" ); // split into lines
for ( int row = 0; row < lines.Count ; row++ ){
var line = lines[row];
var columns = Regex.Split( line, "[\s]+" ); // split into columns
// replace the chosen column for this row
columns[col] = newvalues[row];
// rebuild the line and store it
sb.Append( String.Join( " ", columns );
sb.Append( "\r\n" ); // or whatever line ending you want
}
return sb.ToString();
}
Of course, the above doesn't work too well if your text columns contain whitespace.

// Reads the lines in the file to format.
var fileReader = File.OpenText(filePath + "\\Calculating X,Y File.txt");
// Creates a list for the lines to be stored in.
var fileList = new List<string>();
// Adds each line in the file to the list.
var fileLines = "";
while ((fileLines = fileReader.ReadLine()) != null)
fileList.Add(fileLines);
// Creates new lists to hold certain matches for each list.
var xyResult = new List<string>();
var xResult = new List<string>();
var yResult = new List<string>();
// Iterate over each line in the file and extract the x and y values
fileList.ForEach(line =>
{
Match xyMatch = Regex.Match(line, #"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)");
if (xyMatch.Success)
{
// Grab the x and y values from the regular expression match
String xValue = xyMatch.Groups["x"].Value;
String yValue = xyMatch.Groups["y"].Value;
// Add these two values, separated by a space, to the "xyResult" list.
xyResult.Add(String.Join(" ", new[] { xValue, yValue }));
// Add the results to the lists.
xResult.Add(xValue);
yResult.Add(yValue);
// Store the old X and Y values.
oldXRichTextBox.AppendText(xValue + Environment.NewLine);
oldYRichTextBox.AppendText(yValue + Environment.NewLine);
try
{
// Calculate the X & Y values (including the x & y displacements)
double doubleX = double.Parse(xValue);
double doubleXValue = double.Parse(xDisplacementTextBox.Text);
StringBuilder sbX = new StringBuilder();
sbX.AppendLine((doubleXValue - doubleX).ToString());
double doubleY = double.Parse(yValue);
double doubleYValue = double.Parse(yDisplacementTextBox.Text);
StringBuilder sbY = new StringBuilder();
sbY.AppendLine((doubleY + doubleYValue).ToString());
calculateXRichTextBox.AppendText(sbX + "");
calculateYRichTextBox.AppendText(sbY + "");
// Removes the blank lines.
calculateXRichTextBox.Text = Regex.Replace(calculateXRichTextBox.Text, #"^\s*$(\n|\r|\r\n)", "", RegexOptions.Multiline);
calculateYRichTextBox.Text = Regex.Replace(calculateYRichTextBox.Text, #"^\s*$(\n|\r|\r\n)", "", RegexOptions.Multiline);
}

Related

Remove characters before character “|”

I have a software which needs to remove all of the characters before "|".
For example input
" text needs to removed | Text needs to stay "
An example output will be
"Text needs to stay"
I have the code down below. It works for single-line text but doesn't work on multiple lines. (only removes the text on the first line rest of them stays the same)
I need to make it work with multiple lines. Any ideas?
string input = richTextBox.Text;
string output = input.Substring(input.IndexOf('|') + 1);
richTextBox1.Text = output;
You could do it easily using the Lines property and a temporary List<string> to store the result of substring
List<string> newLines = new List<string>();
foreach (string s in richTextBox1.Lines)
{
// If you want only the lines with the | remove the else block
int x = s.IndexOf('|');
if(x > -1)
newLines.Add(s.Substring(x + 1).Trim());
else
newLines.Add(s);
}
richTextBox1.Lines = newLines.ToArray();
string output = "";
var myArray = input.Split("\r\n");
foreach(var ar in myArray)
if(ar.Length > 0)
output+= ar.Substring(0, ar.IndexOf('|')) + "\r\n";
Oups! i returned the first part, but i suppose you got the point
What about using LINQ for this.
E.g.:
List<string> lines = yourString.Split("\n"); //Add \r if needed
List<string> smallerLines = lines.Select(x => x.Skip(x.IndexOf('|')+1));
If needed you can always create one new string of the output:
string finalString = String.Join(String.Empty, smallerLines);
string input = richTextBox1.Text;
int len = richTextBox1.Lines.Length;
string output = "";
for (int i = 0; i <len; i++)
{
if(i!=len-1)
{
output += richTextBox1.Lines[i].Substring(input.IndexOf('|') + 1) +
Environment.NewLine;
}
else
{
output += richTextBox1.Lines[i].Substring(input.IndexOf('|') + 1);
}
}
richTextBox1.Text = output;

Download string from website, check each line if it contains string

I have created a simple page that contains plain text like this:
Line 1
Line 2
Line 3
Line 4
And I made a c# Winform app that contains a textbox
Textbox text is like
Line 1
Line 2
I want to check if a textbox line contains any of downloaded string from my website
here's what i tried but doesn't work
int pub = 0;
int priv = 0;
WebClient data = new WebClient();
string reply = data.DownloadString("http://mytoosupd.000webhostapp.com/public-keys.html");
for (int i=0; i < textBox1.Lines.Length; i++)
{
if (textBox1.Lines[i].Contains(reply + "\n"))
{
pub++;
label5.Text = pub.ToString();
continue;
}
else if (!textBox1.Lines[i].Contains(reply))
{
priv++;
label4.Text = priv.ToString();
}
}
Split, Intersect, Any would be easy enough
string reply = data.DownloadString(..);
var result = reply
.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries)
.Intersect(textBox1.Lines)
.Any();
Debug.WriteLine($"Found = {result}");
Update
// to get a list of the intersected lines, call `ToList()` instead
var list = reply
.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.RemoveEmptyEntries)
.Intersect(textBox1.Lines)
.ToList();
// list.Count() to get the count
// use this list where ever you like
// someTextBox.Text = String.Join(Environment.NewLine, list);
// or potentially
// someTextBox.Lines = list.ToArray();

string.PadRight() doesn't seem to work in my code

I have a Powershell output to re-format, because formatting gets lost in my StandardOutput.ReadToEnd().There are several blanks to be removed in a line and I want to get the output formatted readable.
Current output in my messageBox looks like
Microsoft.MicrosoftJigsaw All
Microsoft.MicrosoftMahjong All
What I want is
Microsoft.MicrosoftJigsaw All
Microsoft.MicrosoftMahjong All
What am I doing wrong?
My C# knowledge still is basic level only
I found this question here, but maybe I don't understand the answer correctly. The solution doesn't work for me.
Padding a string using PadRight method
This is my current code:
string first = "";
string last = "";
int idx = line.LastIndexOf(" ");
if (idx != -1)
{
first = line.Substring(0, idx).Replace(" ","").PadRight(10, '~');
last = line.Substring(idx + 1);
}
MessageBox.Show(first + last);
String.PadLeft() first parameter defines the length of the padded string, not padding symbol count.
Firstly, you can iterate through all you string, split and save.
Secondly, you should get the longest string length.
Finally, you can format strings to needed format.
var strings = new []
{
"Microsoft.MicrosoftJigsaw All",
"Microsoft.MicrosoftMahjong All"
};
var keyValuePairs = new List<KeyValuePair<string, string>>();
foreach(var item in strings)
{
var parts = item.Split(new [] {" "}, StringSplitOptions.RemoveEmptyEntries);
keyValuePairs.Add(new KeyValuePair<string, string>(parts[0], parts[1]));
}
var longestStringCharCount = keyValuePairs.Select(kv => kv.Key).Max(k => k.Length);
var minSpaceCount = 5; // min space count between parts of the string
var formattedStrings = keyValuePairs.Select(kv => string.Concat(kv.Key.PadRight(longestStringCharCount + minSpaceCount, ' '), kv.Value));
foreach(var item in formattedStrings)
{
Console.WriteLine(item);
}
Result:
Microsoft.MicrosoftJigsaw All
Microsoft.MicrosoftMahjong All
The PadRight(10 is not enough, it is the size of the complete string.
I would probably go for something like:
string[] lines = new[]
{
"Microsoft.MicrosoftJigsaw All",
"Microsoft.MicrosoftMahjong All"
};
// iterate all (example) lines
foreach (var line in lines)
{
// split the string on spaces and remove empty ones
// (so multiple spaces are ignored)
// ofcourse, you must check if the splitted array has atleast 2 elements.
string[] splitted = line.Split(new Char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// reformat the string, with padding the first string to a total of 40 chars.
var formatted = splitted[0].PadRight(40, ' ') + splitted[1];
// write to anything as output.
Trace.WriteLine(formatted);
}
Will show:
Microsoft.MicrosoftJigsaw All
Microsoft.MicrosoftMahjong All
So you need to determine the maximum length of the first string.
Assuming the length of second part of your string is 10 but you can change it. Try below piece of code:
Function:
private string PrepareStringAfterPadding(string line, int totalLength)
{
int secondPartLength = 10;
int lastIndexOfSpace = line.LastIndexOf(" ");
string firstPart = line.Substring(0, lastIndexOfSpace + 1).Trim().PadRight(totalLength - secondPartLength);
string secondPart = line.Substring(lastIndexOfSpace + 1).Trim().PadLeft(secondPartLength);
return firstPart + secondPart;
}
Calling:
string line1String = PrepareStringAfterPadding("Microsoft.MicrosoftJigsaw All", 40);
string line2String = PrepareStringAfterPadding("Microsoft.MicrosoftMahjong All", 40);
Result:
Microsoft.MicrosoftJigsaw All
Microsoft.MicrosoftMahjong All
Note:
Code is given for demo purpose please customize the totalLength and secondPartLength and calling of the function as per your requirement.

split string in to several strings at specific points

I have a text file with lines of text laid out like so
12345MLOL68
12345MLOL68
12345MLOL68
I want to read the file and add commas to the 5th point, 6th point and 9th point and write it to a different text file so the result would be.
12345,M,LOL,68
12345,M,LOL,68
12345,M,LOL,68
This is what I have so far
public static void ToCSV(string fileWRITE, string fileREAD)
{
int count = 0;
string x = "";
StreamWriter commas = new StreamWriter(fileWRITE);
string FileText = new System.IO.StreamReader(fileREAD).ReadToEnd();
var dataList = new List<string>();
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
foreach (string y in splitString)
{
dataList.Add(y);
}
foreach (string y in dataList)
{
x = (x + y + ",");
count++;
if (count == 3)
{
x = (x + "NULL,NULL,NULL,NULL");
commas.WriteLine(x);
x = "";
count = 0;
)
}
commas.Close();
}
The problem I'm having is trying to figure out how to split the original string lines I read in at several points. The line
IEnumerable<string> splitString = Regex.Split(FileText, "(.{1}.{5})").Where(s => s != String.Empty);
Is not working in the way I want to. It's just adding up the 1 and 5 and splitting all strings at the 6th char.
Can anyone help me split each string at specific points?
Simpler code:
public static void ToCSV(string fileWRITE, string fileREAD)
{
string[] lines = File.ReadAllLines(fileREAD);
string[] splitLines = lines.Select(s => Regex.Replace(s, "(.{5})(.)(.{3})(.*)", "$1,$2,$3,$4")).ToArray();
File.WriteAllLines(fileWRITE, splitLines);
}
Just insert at the right place in descending order like this.
string str = "12345MLOL68";
int[] indices = {5, 6, 9};
indices = indices.OrderByDescending(x => x).ToArray();
foreach (var index in indices)
{
str = str.Insert(index, ",");
}
We're doing this in descending order because if we do other way indices will change, it will be hard to track it.
Here is the Demo
Why don't you use substring , example
editedstring=input.substring(0,5)+","+input.substring(5,1)+","+input.substring(6,3)+","+input.substring(9);
This should suits your need.

How to get value specific column value in csv using c#?

I do a project in c# winforms.
I want to get first column value in csv.
var reader = new StreamReader(File.OpenRead(#"C:\test.csv"));
List<string> listA = new List<string>();
List<string> listB = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
var values = line.Split(';');
listA.Add(values[0]);
}
------------------
no |name |
------------------
1 |wwwwww
2 |yyyyy
3 |aaaaa
4 |bbbbbb
Now I am using above this code. It gives the value row by row. i want all name value in listA
Any one have idea?
There is now way to read column in CSV without reading whole file. You can use some wrappers (for example: LINQ to CSV library) but they will just "hide" reading operation.
Yes - you're currently spliting on ;
Try using a comma instead.
Better to use a dedicated library btw...
Some frown upon Regex but I think it provides good flexibility. Here is an example inspired by
Adrian Mejia. Basically, you can choose particular characters between which the delimiter is valid in the context. i.e. a comma in "hello, world" or 'hello, world' would be valid.
static void Main(string[] args)
{
string csv = "Hello,1,3.5,25,\"speech marks\",'inverted commas'\r\nWorld,2,4,60,\"again, more speech marks\",'something else in inverted commas, with a comma'";
// General way to create grouping constructs which are valid 'text' fields
string p = "{0}([^{0}]*){0}"; // match group '([^']*)' (inverted commas) or \"([^\"]*)\" (speech marks)
string c = "(?<={0}|^)([^{0}]*)(?:{0}|$)"; // commas or other delimiter group (?<=,|^)([^,]*)(?:,|$)
char delimiter = ','; // this can be whatever delimiter you like
string p1 = String.Format(p, "\""); // speechmarks group (0)
string p2 = String.Format(p, "'"); // inverted comma group (1)
string c1 = String.Format(c, delimiter); // delimiter group (2)
/*
* The first capture group will be speech marks ie. "some text, "
* The second capture group will be inverted commas ie. 'this text'
* The third is everything else seperated by commas i.e. this,and,this will be [this][and][this]
* You can extend this to customise delimiters that represent text where a comma between is a valid entry eg. "this text, complete with a pause, is perfectly valid"
*
* */
//string pattern = "\"([^\"]*)\"|'([^']*)'|(?<=,|^)([^,]*)(?:,|$)";
string pattern = String.Format("{0}|{1}|{2}", new object[] { p1, p2, c1 }); // The actual pattern to match based on groups
string text = csv;
// If you're reading from a text file then this will do the trick. Uses the ReadToEnd() to put the whole file to a string.
//using (TextReader tr = new StreamReader("PATH TO MY CSV FILE", Encoding.ASCII))
//{
// text = tr.ReadToEnd(); // just read the whole stream
//}
string[] lines = text.Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); // if you have a blank line just remove it?
Regex regex = new Regex(pattern, RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase); // compile for speed
List<object> rowsOfColumns = new List<object>();
foreach (string row in lines)
{
List<string> columns = new List<string>();
// Find matches.
MatchCollection matches = regex.Matches(row);
foreach (Match match in matches)
{
for (int ii = 0; ii < match.Groups.Count; ii++)
{
if (match.Groups[ii].Success) // ignore things that don't match
{
columns.Add(match.Groups[ii].Value.TrimEnd(new char[] { delimiter })); // strip the delimiter
break;
}
}
}
// Do something with your columns here (add to List for example)
rowsOfColumns.Add(columns);
}
}
var reader = new StreamReader(File.OpenRead(#"C:\test.csv"));
List<string> listA = new List<string>();
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
string[] dates = line.Split(',');
for (int i = 0; i < dates.Length; i++)
{
if(i==0)
listA.Add(dates[0]);
}
}

Categories

Resources