Find and replace string spanned multiline - c#

I have a file and I need to find a particular string and replace it with another string. The file is created or submitted to us by an external system. The submitted file has 80 characters per line. If a word in the text file doesn't fit into one line, it is split into 2 lines delimited by = symbol at the end of the first line. In the below example, the SAMPLE STRING is split into 2 lines, SAM= in the first line and PLE STRING in the second line. An example is given below
Line 1 text goes here SAM=
PLE STRING and the other texts of the file.
Now I need to find if SAMPLE STRING exists, and then replace with some other sample string. I wrote the below code in C#, but unable to find the string if it spans over multiple lines. Please help.
string filecontents = System.IO.File.ReadAllText("c:\\mytext.txt");
if(filecontents.Contains("SAMPLE STRING"))
{
filecontents = filecontents.Replace("SAMPLE STRING", "SOME_OTHER_STRING");
}

string filecontents = File.ReadAllText("c:\\mytext.txt");
// rebuild the splitted strings
filecontents = filecontents.Replace("=" + System.Environment.NewLine, "");
// remove line breaks from text
filecontents = filecontents.Replace(System.Environment.NewLine, " ");
// no need to use the Contains check, use a straightforward replacement (it will do nothing if the string is not present)
filecontents = filecontents.Replace("SAMPLE STRING", "SOME_OTHER_STRING");
Once this is done, resplit your text into multiple lines with the same criteria. Since the string that replaces your sample has a different length, if you don't perform the replacement using this approach (or an equivalent one) you will end up with your text splitted into lines of unequal length.

Related

How can i append RN/ line to upper line without RN/ in C#?

R/DOCS HK1/P/XX/123456789/XX/XXXXX/M/XXXXX/STAC
RN/K/OVER/FLOW
I need to merge above text like the below;
R/DOCS HK1/P/XX/123456789/XX/XXXXX/M/XXXXX/STACK/OVER/FLOW
The second line starts with RN/ which means everything after the slash should be appended to the previous line.
I searching with foreach. So i can't add as a string.
If the content you want to add from the second string always starts after "RN/", you can do it like this:
string string1 = "R/DOCS HK1/P/XX/123456789/XX/XXXXX/M/XXXXX/STAC";
string string2 = "RN/K/OVER/FLOW";
string result = string1 + string2.Substring(3);

C# Regex Replacement Not Working

I'm trying to remove new lines from a text file. Opening the text file in notepad doesn't reveal the line breaks I'm trying to remove (it looks like one big wall of text), however when I open the file in sublime, I can see them.
In sublime, I can remove the pattern '\n\n' and then the pattern '\n(?!AAD)' no problem. However, when I run the following code, the resulting text file is unchanged:
public void Format(string fileloc)
{
string str = File.ReadAllText(fileloc);
File.WriteAllText(fileloc + "formatted", Regex.Replace(Regex.Replace(str, "\n\n", ""), "\n(?!AAD)", ""));
}
What am I doing wrong?
If you do not want to spend hours trying to re-adjust the code for various types of linebreaks, here is a generic solution:
string str = File.ReadAllText(fileloc);
File.WriteAllText(fileloc + "formatted",
Regex.Replace(Regex.Replace(str, "(?:\r?\n|\r){2}", ""), "(?:\r?\n|\r)(?!AAD)", "")
);
Details:
A linebreak can be matched with (?:\r?\n|\r): an optional CR followed with a single obligatory LF. To match 2 consecutive linebreaks, a limiting quantifier can be appended - (?:\r?\n|\r){2}.
An empirical solution. Opening your sample file in binary mode revealed that it contains 0x0D characters, which are carriage returns \r. So I came up with this (multiple lines for easier debugging):
public void Format(string fileloc)
{
var str = File.ReadAllText(fileloc);
var firstround = Regex.Replace(str, #"\r\r", "");
var secondround = Regex.Replace(firstround, #"\r(?!AAD)", "");
File.WriteAllText(fileloc + "formatted", secondround);
}
Is this possibly a windows/linux mismatch? Try replacing '\r\n' instead.

Read a last line containing string in a text file?

i have a text file:
ABCD - 11111
111212
13121
ABCD - 1213
12312
34534
ABCD - 21312
123123
123123
How do i to read from last line start with 'ABCD' to end of file. In the above example, result is:
ABCD - 21312
123123
123123
If you read the file into a string, you can accomplish this by using Substring and LastIndexOf.
string inputText = "ABCD - 11111\n111212\n13121\n\n\n" +
"ABCD - 1213\n12312\n34534\n\n\nABCD - 21312\n123123\n123123";
string remainingText = inputText.Substring(inputText.LastIndexOf("ABCD"));
LastIndexOf will determine the last index where the string ABCD occurs (in this case, 54).
Substring will then remove all text occurring before that index to give you the result you expect.
Therefore remainingText will contain the value:
ABCD - 21312\n123123\n123123
First read the file into an string then use LastIndexOf("ABCD") to find the position of last occurrence of your pattern and finally use SubString to extract it.
string path = #"c:\temp\MyTest.txt";
string readText = File.ReadAllText(path);
int position = readText.LastIndexOf("ABCD");
string toEnd = readText.Substring(position ,readText.Length - position).
Using the System.IO namespace's method File.ReasAllText will read the content of the txt file. Assign the value to string variable.
File.ReadAllText("sample.txt");
Then find the last occurrence of the string ABCD
// Find the last occurrence of ABCD.
int index = sString.LastIndexOf('ABCD');
Then using substring get the string value from last index.
string subStr = sString.Substring(index);
If you want some performance or efficiency I wouldn't read the entire file into memory (especially if it is going to be big). I would use FileStreams with Seek method to start reading from the end of the file last three lines. The exact implementation depends of your data format. In case you don't have a strict format of last three lines then read from the end byte per byte until you read three new lines. Of course the code is not so simple but you gain the best efficiency.

How to read a file into a string with CR/LF preserved?

If I asked the question "how to read a file into a string" the answer would be obvious. However -- here is the catch with CR/LF preserved.
The problem is, File.ReadAllText strips those characters. StreamReader.ReadToEnd just converted LF into CR for me which led to long investigation where I have bug in pretty obvious code ;-)
So, in short, if I have file containing foo\n\r\nbar I would like to get foo\n\r\nbar (i.e. exactly the same content), not foo bar, foobar, or foo\n\n\nbar. Is there some ready to use way in .Net space?
The outcome should be always single string, containing entire file.
Are you sure that those methods are the culprits that are stripping out your characters?
I tried to write up a quick test; StreamReader.ReadToEnd preserves all newline characters.
string str = "foo\n\r\nbar";
using (Stream ms = new MemoryStream(Encoding.ASCII.GetBytes(str)))
using (StreamReader sr = new StreamReader(ms, Encoding.UTF8))
{
string str2 = sr.ReadToEnd();
Console.WriteLine(string.Join(",", str2.Select(c => ((int)c))));
}
// Output: 102,111,111,10,13,10,98,97,114
// f o o \n \r \n b a r
An identical result is achieved when writing to and reading from a temporary file:
string str = "foo\n\r\nbar";
string temp = Path.GetTempFileName();
File.WriteAllText(temp, str);
string str2 = File.ReadAllText(temp);
Console.WriteLine(string.Join(",", str2.Select(c => ((int)c))));
It appears that your newlines are getting lost elsewhere.
This piece of code will preserve LR and CR
string r = File.ReadAllText(#".\TestData\TR120119.TRX", Encoding.ASCII);
The outcome should be always single string, containing entire file.
It takes two hops. First one is File.ReadAllBytes() to get all the bytes in the file. Which doesn't try to translate anything, you get the raw data in the file so the weirdo line-endings are preserved as-is.
But that's bytes, you asked for a string. So second hop is to apply Encoding.GetString() to convert the bytes to a string. The one thing you have to do is pick the right Encoding class, the one that matches the encoding used by the program that wrote the file. Given that the file is pretty messed up if it contains \n\r\n sequences, and you didn't document anything else about the file, your best bet is to use Encoding.Default. Tweak as necessary.
You can read the contents of a file using File.ReadAllLines, which will return an array of the lines. Then use String.Join to merge the lines together using a separator.
string[] lines = File.ReadAllLines(#"C:\Users\User\file.txt");
string allLines = String.Join("\r\n", lines);
Note that this will lose the precision of the actual line terminator characters. For example, if the lines end in only \n or \r, the resulting string allLines will have replaced them with \r\n line terminators.
There are of course other ways of acheiving this without losing the true EOL terminator, however ReadAllLines is handy in that it can detect many types of text encoding by itself, and it also takes up very few lines of code.
ReadAllText doesn't return carriage returns.
This method opens a file, reads each line of the file, and then adds each line as an element of a string. It then closes the file. A line is defined as a sequence of characters followed by a carriage return ('\r'), a line feed ('\n'), or a carriage return immediately followed by a line feed. The resulting string does not contain the terminating carriage return and/or line feed.
From MSDN - https://msdn.microsoft.com/en-us/library/ms143368(v=vs.110).aspx
This is similar to the accepted answer, but wanted to be more to the point. sr.ReadToEnd() will read the bytes like is desired:
string myFilePath = #"C:\temp\somefile.txt";
string myEvents = String.Empty;
FileStream fs = new FileStream(myFilePath, FileMode.Open);
StreamReader sr = new StreamReader(fs);
myEvents = sr.ReadToEnd();
sr.Close();
fs.Close();
You could even also do those in cascaded using statements. But I wanted to describe how the way you write to that file in the first place will determine how to read the content from the myEvents string, and might really be where the problem lies. I wrote to my file like this:
using System.Reflection;
using System.IO;
private static void RecordEvents(string someEvent)
{
string folderLoc = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if (!folderLoc.EndsWith(#"\")) folderLoc += #"\";
folderLoc = folderLoc.Replace(#"\\", #"\"); // replace double-slashes with single slashes
string myFilePath = folderLoc + "myEventFile.txt";
if (!File.Exists(myFilePath))
File.Create(myFilePath).Close(); // must .Close() since will conflict with opening FileStream, below
FileStream fs = new FileStream(myFilePath, FileMode.Append);
StreamWriter sr = new StreamWriter(fs);
sr.Write(someEvent + Environment.NewLine);
sr.Close();
fs.Close();
}
Then I could use the code farther above to get the string of the contents. Because I was going further and looking for the individual strings, I put this code after THAT code, up there:
if (myEvents != String.Empty) // we have something
{
// (char)2660 is ♠ -- I could have chosen any delimiter I did not
// expect to find in my text
myEvents = myEvents.Replace(Environment.NewLine, ((char)2660).ToString());
string[] eventArray = myEvents.Split((char)2660);
foreach (string s in eventArray)
{
if (!String.IsNullOrEmpty(s))
// do whatever with the individual strings from your file
}
}
And this worked fine. So I know that myEvents had to have the Environment.NewLine characters preserved because I was able to replace it with (char)2660 and do a .Split() on that string using that character to divide it into the individual segments.

How do I save a multi-line textbox as one line to a text file?

Ok guys, I am making a function to save a file. I have come across a problem in that when I save the data from multi-line text boxes it saves x amount of lines as x amount of lines in the text file.
So for example if the user entered:
line one
line two
line three
it would show as:
line one
line two
line three
as I want it to display as:
line one \n line two \n line three \n
The code I have is:
savefile.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
savefile.Title = "Save your file";
savefile.FileName = "";
savefile.Filter = "ChemFile (*.cd)|*.cd|All Files|*.*";
if (savefile.ShowDialog() != DialogResult.Cancel)
{
// save the text file information
for (int i = 0; i < noofcrit; i++)
{
cdfile[i] = crittextbs[i].Text;
}
}
// Compile the file
SaveFile = savefile.FileName;
System.IO.File.WriteAllLines(SaveFile, cdfile);
Any ideas how I can save multiline text files as one line? Thanks.
Replace Newline character with #" \n "or" \\n ", using # to ignore any escape char
string s= yourTextBox.Text.Replace(Environment.NewLine, #" \n "));
I think you may need to do something like this. I'm not actually sure what the best way is to show escape characters. Also, I would use a StreamWriter.
string myData = txtMyTextBox.Text.Replace("\r"," \\r ").Replace("\n"," \\n ");
using(System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath))
{
sw.Write(myData);
}
If you get the multi-line strings in a string array, you could just join them into a single line:
string[] multiline = new []{"multi","line","text"};
string singleLine = string.Join(#"\n",multiline);
if it's all a single line, a simple Replace would do the trick,
string singleLine = multiline.Replace("\r",string.Empty).Replace("\n",#"\n");
It's all one line really ;)
Multi-line text boxes depending on platform (Win32 here) will save as:
Line\r\n
Line\r\n
Line\r\n
So you just need to replace \r\n with \n or whatever character replacement you want.

Categories