Process multiline text in C# - c#

I am trying to process some text with unusual pattern. The text looks like below:
||Names : XYZ DJ Age : 23 Years Location: New York; end;'
2018-03-20 11:59:59.397, mnx=0x0000700, pid=90c9ac, xSG: dlgID:34
AppDlg:774 params: 2018-03-20 11:59:59.397, mnx=0x700000,
pid=090c9ac, lBG: OPCDManager::Response: 0x7f083 2018-03-20
11:59:59.397, mxn=0x000070, pid=f90c9ac, lBG: DlgID:37774 sess:'990'
conID:1 dlClose:false params:
Now, I want to load this data into a text file as below:
XYZ DJ-23 Years-New York,2018-03-20 11:59:59.397, mnx=0x0000700,
pid=90c9ac, xSG: dlgID:34 AppDlg:774 params: XYZ DJ-23 Years-New
York,2018-03-20 11:59:59.397, mnx=0x700000, pid=090c9ac,
lBG: OPCDManager::Response: 0x7f083 XYZ DJ-23 Years-New
York,2018-03-20 11:59:59.397, mxn=0x000070, pid=f90c9ac,
lBG: DlgID:37774 sess:'990' conID:1 dlClose:false params:
I have tried the below code but it does not give me what I want. Instead, it gives me one long text strings instead of several rows:
string linesc = File.ReadAllText(path);
string[] linesx = linesc.Split('|');
foreach (string s in linesx)
{
string new2=s.Replace(Environment.NewLine, " ");
File.AppendAllText(path2 + "myfile.txt", new2 + Environment.NewLine);
}
How can I modify the code so that I get the rows above?

Try the following:
string linesc = File.ReadAllText(path);
string[] linesx = linesc.Split('|');
foreach (string s in linesx)
{
string new2=s.Replace(Environment.NewLine, " ")
.Replace("Names : ", "")
.Replace("Age : ", "")
.Replace("Location : ", "") + "\n";
File.AppendAllText(path2 + "myfile.txt", new2 + Environment.NewLine);
}
I also took care of removing "Name : ", "Age : " and "Location : " from the input.

You can also try this approach:
string text = #"||Names : XYZ DJ
Age : 23 Years
Location: New York; end;'
2018-03-20 11:59:59.397, mnx=0x0000700, pid=90c9ac, xSG: dlgID:34 AppDlg:774 params:
2018-03-20 11:59:59.397, mnx=0x700000, pid=090c9ac, lBG: OPCDManager::Response: 0x7f083
2018-03-20 11:59:59.397, mxn=0x000070, pid=f90c9ac, lBG: DlgID:37774 sess:'990' conID:1 dlClose:false params:";
StringBuilder result = new StringBuilder();
string[] allLines = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
string name = allLines[0].Replace("||Names : ", string.Empty).Trim();
string age = allLines[1].Replace("Age : ", string.Empty).Replace("Years", string.Empty).Trim();
string location = allLines[2].Replace("Location: ", string.Empty).Replace("; end;'", string.Empty).Trim();
for(int i = 3; i < allLines.Length; i++)
{
result.AppendLine($"{name}-{location},{allLines[i].Trim()}");
}
string res = result.ToString();
Console.WriteLine(res);

You have to break this down into several steps:
extract the 'global' information from the first three lines
iterate over the listing lines and concatenate them to the output format
At the moment you are splitting by '|' which results in ["", "", "Names : XYZ ... your whole other text"].
So for example (not tested):
string[] linesc = File.ReadAllText(path).Split(new string[]{Environment.NewLine}, StringSplitOptions.None);
// extract global infos
string[] name = linesc[0].Split(':');
string[] age = linesc[1].Split(':');
string[] location = linesc[2].Split(':');
for (int i=3; i<linesc.Length; i++)
{
// reconcatenate new line
string new2 = name[1] + "-" + age[1] + "-" + location[1] + "," + linesc[i];
File.AppendAllText(path2 + "myfile.txt", new2 + Environment.NewLine);
}
If you also want to get rid of leading/trailing spaces you can use Trim() on each of the string parts.

Related

How to add a string of text into another txt file

I have this txt file that contains this text:
MSH^~|\&^R3POCQUERYS^050~BCMABU.MED.VA.GOV~DNS^R3POCQUERYR^^201711081317040500^^RQC~I06^50279320^D^2.5^^^AL^NE^USA
QRD^20171108131704-0500^R^I^WQRY^^^^SSN~%ABC123^9A-MED~WA0034^^^T
but I only want the values that come after SSN~% and after the MED~
I want to be able read from the Line that starts with QRD and then be able to grab ANY value after SSN~% and MED~, so the value can be anything I'm just using ABC123 and WA0034 as examples.
Form1.cs
private void Parse(string filename)
{
string line;
var str = File.ReadAllText(filename);
System.IO.StreamReader file = new System.IO.StreamReader(filename);
targetRichTextBox = richTextBox1;
WriteTextSafelyInRichTextBox(str);
while ((line = file.ReadLine()) != null)
{
if ((line.Contains("QRD"))
{
//Enter code here
}
}
char[] delimiterChars = { '^' };
string[] words = str.Split(delimiterChars);
var createText = (RetrunTemplate.Get().Replace(words[24], "VHIC-").Replace(words[25], "9A-MED~WA0034"));
var outputFilename = outputDir + "\\OutboundMessage - " + DateTime.UtcNow.ToString("yyyy-MM-dd HH-mm-ss-ff", CultureInfo.InvariantCulture) + ".txt";
File.WriteAllText(outputFilename, createText);
targetRichTextBox = richTextBox2;
WriteTextSafelyInRichTextBox(createText);
file.Close();
File.Delete(filename);
MessageBox.Show("You have successfuly creatd an outbound Message");
}
RetrunTemplate
class RetrunTemplate
{
public static string Get()
{
string retrunTemplate = #"MSH^~|\&^R3POCSEND^442~CHEY209.FO-BAYPINES.MED.VA.GOV~DNS^R3POCRCV^^20171108131710-0400^^RCL~I06^442157252912^D^2.5^^^AL^NE^USA" + Environment.NewLine +
"PID^^^4420041228V165312~~~USVHA&&0363~NI~VA FACILITY ID&442&L~~20171108|666393848~~~" + Environment.NewLine +
#"USSSA&&0363~SS~VA FACILITY ID&442&L|""~~~USDOD&&0363~TIN~VA FACILITY ID&442&L" + Environment.NewLine +
#"""~~~USDOD&&0363~FIN~VA FACILITY ID&442&L|7209344~~~USVHA&&0363~PI~VA FACILITY ID&442&L" + Environment.NewLine +
#"^VHIC-ABC123~~~USVHA&&0363~PI~VA FACILITY ID&742V1&L^ZEIGLER~PG~EIGHT~~~~L" + Environment.NewLine +
#"|""~~~~~~N^^19220304^M^^^9234234~""~SAN FRANCISCO~CA~94114~USA~P~""~075|~~SAN JOSE~CO~~""~N^^""^^^^^^^^^^^^^^^^^^" + Environment.NewLine +
#"PV1^^^9A-MED" + Environment.NewLine + "HH1^WA0034";
return retrunTemplate;
}
}
Suppose you read the file line by line. You can validate each line against the following Regex, and extract what you want.
var text = "QRD^20171108131704-0500^R^I^WQRY^^^^SSN~%ABC123^9A-MED~WA0034^^^T";
var rgx = new Regex(#"QRD.+SSN~%(.+)MED~(.+)");
var match = rgx.Match(text);
if (match.Success)
{
Console.WriteLine(match.Groups[1].Value);
Console.WriteLine(match.Groups[2].Value);
}
The match.Groups[1] has ABC123^9A-, and match.Groups[2] has WA0034^^^T. You can now do what you will with those text.
Regex Breakdown
#"QRD.+SSN~%(.+)MED~(.+)"
QRD - Starts with the string QRD
.+ - Followed by one or more characters
SSN~% - Followed by SSN~~%
(.+) - Grab (to Groups[1]) one or more characters between SSN~% and MED~
MED! - Followed by MED~
(.+) - Grab everything else in the line to Groups[2]
Here's my effort.
var input = #"MSH^~|\&^R3POCQUERYS^050~BCMABU.MED.VA.GOV~DNS^R3POCQUERYR^^201711081317040500^^RQC~I06^50279320^D^2.5^^^AL^NE^USA
QRD^20171108131704-0500^R^I^WQRY^^^^SSN~%ABC123^9A-MED~WA0034^^^T" ;
var pattern = #"SSN\~\%([A-Z0-9]+).*MED\~([A-Z0-9]+)";
var matches = Regex.Matches(input, pattern, RegexOptions.Multiline).
Select( m => new { SSN = m.Groups[1].Value, MED = m.Groups[2].Value});
foreach(var m in matches ) {
Console.WriteLine($"SSN = {m.SSN}, MED = {m.MED}");
}
Output
SSN = ABC123, MED = WA0034
With QRD matching
var input = #"MSH^~|\&^R3POCQUERYS^050~BCMABU.MED.VA.GOV~DNS^R3POCQUERYR^^201711081317040500^^RQC~I06^50279320^D^2.5^^^AL^NE^USA
QRD^20171108131704-0500^R^I^WQRY^^^^SSN~%ABC123^9A-MED~WA0034^^^T";
var pattern = #"SSN\~\%([A-Z0-9]+).*MED\~([A-Z0-9]+)";
var matches = input
.Split()
.Where(l => l.StartsWith("QRD"))
.Select(l => Regex.Matches(l, pattern).Select(m => new { SSN = m.Groups[1].Value, MED = m.Groups[2].Value }));
foreach (var groups in matches)
{
foreach (var g in groups)
{
Console.WriteLine($"SSN = {g.SSN}, MED = {g.MED}");
}
}
Output
SSN = ABC123, MED = WA0034

Split result of WebClient.DownloadString into multiple lines [duplicate]

This question already has answers here:
split a string on newlines in .NET
(17 answers)
Closed 3 years ago.
I am trying to get a line foreach line in a webclient.DownloadString("pastebinsite"); but it says cannot convert type 'char' to 'string', so I add a string[] downloaded = wc.DownloadString(arac[0] + arac[1] + #"//" + arac[2] + "/raw/" + arac[3]);
that does not work because it says cannot convert type 'string' to 'string[]' I am stuck and cannot find a answer online for this.
I have tried changing types
{
StringBuilder sb = new StringBuilder();
Console.WriteLine("start?");
Console.ReadKey();
string[] lines = File.ReadAllLines(Directory.GetCurrentDirectory() + #"\Lines.txt");
WebClient wc = new WebClient();
int _checked = 0;
int _error = 0;
foreach(string line in lines)
{
++_checked;
//Pastebin text viewer
try
{
if (line.Contains("pastebin"))
{
var arac = line.Split('/');
//ERROR LINE CANNOT CONVERT TYPE 'STRING' TO 'STRING[]' Below
string[] downloaded = wc.DownloadString(arac[0] + arac[1] + #"//" + arac[2] + "/raw/" + arac[3]);
foreach(string line2 in downloaded)
{
if (line2.Contains(":")
{
//Console.WriteLine(arac[0] + arac[1] + #"//" + arac[2] + "/raw/" + arac[3]);
Console.WriteLine(arac[0] + arac[1] + #"//" + arac[2] + "/raw/" + arac[3]);
sb.Append(downloaded);
}
}
}
else
{
//Console.WriteLine("Not valid pastebin link!");
}
Console.Title = "Checked : " + _checked;
}
catch(WebException ex)
{
++_error;
Console.WriteLine("Error: " + _error);
}
}
File.WriteAllText(Directory.GetCurrentDirectory() + #"\Output " + _checked + ".txt", sb.ToString());
Console.Clear();
Console.WriteLine("FINISHED");
Console.ReadKey();
}```
wc.DownloadString(..)
returns a string and not a string[].
you need to split the string in order to get a string[]
possible solution if you need that the string[] will contain lines would be:
var stringResult = wc.DownloadString(arac[0] + arac[1] + #"//" + arac[2] + "/raw/" + arac[3]);
then one of the following:
var lines = stringResult.Split(new [] { '\r', '\n' });
var lines = Regex.Split(stringResult, "\r\n|\r|\n");
var lines = stringResult.Split(new[] {"\r\n", "\r", "\n"}, StringSplitOptions.None)
and finally
foreach(string line in lines) {...}

C# - Get All Words Between Chars

I have string:
string mystring = "hello(hi,mo,wo,ka)";
And i need to get all arguments in brackets.
Like:
hi*mo*wo*ka
I tried that:
string res = "";
string mystring = "hello(hi,mo,wo,ka)";
mystring.Replace("hello", "");
string[] tokens = mystring.Split(',');
string[] tokenz = mystring.Split(')');
foreach (string s in tokens)
{
res += "*" + " " + s +" ";
}
foreach (string z in tokenz)
{
res += "*" + " " + z + " ";
}
return res;
But that returns all words before ",".
(I need to return between
"(" and ","
"," and ","
"," and ")"
)
You can try to use \\(([^)]+)\\) regex get the word contain in brackets,then use Replace function to let , to *
string res = "hello(hi,mo,wo,ka)";
var regex = Regex.Match(res, "\\(([^)]+)\\)");
var result = regex.Groups[1].Value.Replace(',','*');
c# online
Result
hi*mo*wo*ka
This way :
Regex rgx = new Regex(#"\((.*)\)");
var result = rgx.Match("hello(hi,mo,wo,ka)");
Split method has an override that lets you define multiple delimiter chars:
string mystring = "hello(hi,mo,wo,ka)";
var tokens = mystring.Replace("hello", "").Split(new[] { "(",",",")" }, StringSplitOptions.RemoveEmptyEntries);

string remove all letters

Why this will print the same result?
string tester = "stUniqueId01";
Debug.WriteLine("ID: " + tester);
var regex = tester.Replace("[^0-9.]", "");
Debug.WriteLine("ID: " + regex);
Output:
ID: stUniqueId01
ID: stUniqueId01
You are calling string.Replace, not Regex.Replace. I think you want:
string tester = "stUniqueId01";
Debug.WriteLine("ID: " + tester);
var regex = new Regex("[^0-9.]");
Debug.WriteLine("ID: " + regex.Replace(tester,""));
or:
string tester = "stUniqueId01";
Debug.WriteLine("ID: " + tester);
var replaced = Regex.Replace(tester,"[^0-9.]","");
Debug.WriteLine("ID: " + replaced);
if you don't intend to reuse the regular expression.
You are using the Replace method from String. It takes strings, not regular expressions. Try:
string tester = "stUniqueId01";
Console.WriteLine("ID: " + tester);
Regex rx = new Regex("[^0-9.]");
var regex = rx.Replace(tester, "");
Console.WriteLine("ID: " + regex);
Result:
ID: stUniqueId01
ID: 01

C# - writing a line to text file after a specific line

I have the following code below and I am trying to ensure that the
line(sw.WriteLine("Test Id: " + testid + " " + "Failed On Event: " + testtype)) ;
is written out to the text file after the line(sw.WriteLine(errLine));.
At the moment when the file is created the lines are not being written to the file in the right order i.e.
sw.WriteLine("Test Id: " + testid + " " + "Failed On Event: " + testtype) - this line appears first
sw.WriteLine(errLine) - appears second.
Just wondering could you help.
using (StreamWriter sw = File.AppendText(#"D:\Temp\Final.txt"))
try
{
string evnt = Convert.ToString(eventid);
string test = Convert.ToString(testid);
Queue<string> lines = new Queue<string>();
using (var filereader = new StreamReader(#"D:\Temp\Outlook.txt"))
{
string line;
while ((line = filereader.ReadLine()) != null)
{
if (line.Contains(evnt) && line.Contains(test) && evnt != oldevent)
{
sw.WriteLine("----- ERROR -----");
foreach (var errLine in lines)
sw.WriteLine(errLine);
oldevent = evnt;
sw.WriteLine("Test Id: " + testid + " " + "Failed On Event: " + testtype);
sw.WriteLine(line);
sw.WriteLine("-----------------");
}
lines.Enqueue(line);
while (lines.Count > 10)
lines.Dequeue();
}
}
}
File is being written from up to bottom. Try taking this line
sw.WriteLine("Test Id: " + testid + " " + "Failed On Event: " + testtype); out of the for loop, before line: foreach (var errLine in lines)
As above you can do below:
File.WriteAllLines(#"D:\Temp\Final.txt", File.ReadLines(#"D:\Temp\Outlook.txt")
.Select(line => line.Contains("Something to find")
? new String[] {"Some caption", line, "More text"}
: new String[] {line};
)
.SelectMany(line => line));
May be Linq is a solution? Something like that:
var source = File
.ReadLines(#"D:\Temp\Outlook.txt")
.Select(line => {
//TODO: put actual code here
if (line.Contains("Something to find"))
return new String[] {"Some caption", line, "More text"};
else
return new String[] {line};
})
.SelectMany(line => line);
File.WriteAllLines(#"D:\Temp\Final.txt", source);

Categories