Remove a specific part of a string - c#

I want to go through a text file and remove specific parts of the string.
In this case I want to remove the path:
PERFORMER "Charles Lloyd"
TITLE "Mirror"
FILE "Charles Lloyd\[2010] Mirror\01. I Fall In Love Too Easily.wav" WAVE
TRACK 01 AUDIO
FILE "Charles Lloyd\[2010] Mirror\02. Go Down Moses.wav" WAVE
to
PERFORMER "Charles Lloyd"
TITLE "Mirror"
FILE "01. I Fall In Love Too Easily.wav" WAVE //here are the changes
TRACK 01 AUDIO
FILE "02. Go Down Moses.wav" WAVE //here are the changes
I tried out things like: (given the string s which contains the whole text)
s = s.Remove(s.IndexOf("FILE") + 5, (s.IndexOf("\\") + 1) - s.IndexOf("FILE") - 5);
and repeat this function to remove the part between "FILE " " and the following backslash
It removes the part correctly, but I would have to manually adjust the number of times it has to run this function (run once for every backslash per line). But this algorithm lacks flexibility and I don't know how to make it approach the next line that starts with "FILE" and begin the procedure again...

If all your text is one string variable, you could first split it, and than do replacements for all strings and than join again (assume your text is variable lines):
var strings = lines.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
var replacedStrings = new List<string>();
foreach (var s in strings)
{
string replaced;
if (s.StartsWith("FILE"))
{
var sWithoutFile = s.Substring(5);
replaced = s.Substring(0, 6) +
sWithoutFile.Substring(sWithoutFile.LastIndexOf("\\") + 1);
}
else
{
replaced = s;
}
replacedStrings.Add(replaced);
}
var result = string.Join(Environment.NewLine, replacedStrings);

What about Regular Expressions.
using System;
using System.Text.RegularExpressions;
class RemovePaths
{
static void Main()
{
string input = #"
PERFORMER ""Charles Lloyd""
TITLE ""Mirror""
FILE ""Charles Lloyd\[2010] Mirror\01. I Fall In Love Too Easily.wav"" WAVE
TRACK 01 AUDIO
FILE ""Charles Lloyd\[2010] Mirror\02. Go Down Moses.wav"" WAVE";
string test = #"
PERFORMER ""Charles Lloyd""
TITLE ""Mirror""
FILE ""01. I Fall In Love Too Easily.wav"" WAVE
TRACK 01 AUDIO
FILE ""02. Go Down Moses.wav"" WAVE";
Regex rgx = new Regex(#"(?<=\"").*\\(?=.+\"")");
string result = rgx.Replace(input, "");
Console.WriteLine(result == test ? "Pass" : "Fail");
}
}
Breakdown of the RegEx...
(?<=\"") <--- must start with a double-quote but be excluded using (?<=...)
.\ <--- match any text up to and including a "\". note: . matches anything
(?=.+\"") <--- skip at least one character(.+) and it must end with a double-quote(\").

Assuming that your line always start with FILE " and EndsWith " WAVE, you can use System.Io.Path.GetFilename() Function to achieve this:
If str.StartsWith("File"){
string strResult = "FILE """ + IO.Path.GetFileName(str.Substring(6,str.Length - 12)) + """ WAVE";
}
Example:
FILE "Charles Lloyd\[2010] Mirror\01. I Fall In Love Too Easily.wav" WAVE
Result:
FILE "01. I Fall In Love Too Easily.wav" WAVE
You can read more about this Function in this MSDN article

Split the array using character \ and store the last element in the array back to the string.
For Example something like this:
array = file.split('\')
file = array[array.size - 1];

Related

How to repeat this for every line in rich text box?

I am currently making myself a little tool.
Essentially I have this list which goes like this:
NPWR00160_00 LittleBigPlanet
NPWR00163_00 Warhawk
NPWR00179_00 Pure
NPWR00180_00 Midnight Club: Los Angeles
NPWR00181_00 echochromeâ„¢
NPWR00187_00 WipEout® HD
This is currently typed into a richTextBox.
I am trying to do this, get the NPWRXXXXXX of the line and save it as a string, and then the Games Name and save that as another string for which I can go ahead and do what I was originially going to do with it. But for each line of the richTextBox which carries on with that formation as above.
Not too sure how to get a line from the richTextBox and save it as a string, in which I can repeat that process for every single line of the richTextBox.
For what I have tried, I gave myself an example that the string was NPWR02727_00 Skydive: Proximity Flight. What I did was this:
string game = "NPWR02727_00 Skydive: Proximity Flight";
string NPWR = game.Substring(0,13);
string gamename = game.Remove(0, 13);
richTextBox2.AppendText("NPWRID: " + NPWR + " Game: " + gamename + Environment.NewLine);
Which actually does successfully save the strings and write it in the second text box as the new form.
Only issue is I'm not sure how to convert a line from the RichTextBox and turn it into a string, and repeat the process for each line in the rich text box
EDIT
So I found out how to turn a string into a line from the richTextBox..
string line = richTextBox1.Lines[0];
So this will get the first line and save it as the string "line"
This now updates the code to
string game = richTextBox1.Lines[0];
string NPWR = game.Substring(0,13);
string gamename = game.Remove(0, 13);
richTextBox2.AppendText("NPWRID: " + NPWR + " Game: " + gamename + Environment.NewLine);
Now how do I get this code to run for every line, I understand I need something to repeat it, and something to change the 0 to count up by 1 everytime it repeats?
EDIT AGAIN
Awesome, forget the above edit, thanks a lot!
I suggest you do something similar to this:
var codes = new List<string>();
var games = new List<string>();
foreach(var s in richTextBox1.Lines)
{
string[] p = s.Split(new char[] { ' ' }, 2);
if (p.Count() == 1) { continue; }
codes.Add(p[0]);
games.Add(p[1]);
}
Basically, we are declaring two Lists of the type string, to store respectively the code and the name of the game. Then we proceed in looping through the Lines property of the RichTextBox, and for each line, we split the line by the first index(space) we find; asking for a maximum of two strings, to avoid splitting any forthcoming elements; in case the name of the game contains spaces.
For the two substrings obtained, we proceed by saving the first part into the List codes, and the second one into the List games.
For further uses(traversing codes/names) we could access the two Lists
for(int c = 0; c < codes.Count; c++)
{
MessageBox.Show(codes[c] + string.Empty + games[c]);
}

Alternative to File.AppendAllText for newline

I am trying to read characters from a file and then append them in another file after removing the comments (which are followed by semicolon).
sample data from parent file:
Name- Harly Brown ;Name is Harley Brown
Age- 20 ;Age is 20 years
Desired result:
Name- Harley Brown
Age- 20
I am trying the following code-
StreamReader infile = new StreamReader(floc + "G" + line + ".NC0");
while (infile.Peek() != -1)
{
letter = Convert.ToChar(infile.Read());
if (letter == ';')
{
infile.ReadLine();
}
else
{
System.IO.File.AppendAllText(path, Convert.ToString(letter));
}
}
But the output i am getting is-
Name- Harley Brown Age-20
Its because AppendAllText is not working for the newline. Is there any alternative?
Sure, why not use File.AppendAllLines. See documentation here.
Appends lines to a file, and then closes the file. If the specified file does not exist, this method creates a file, writes the specified lines to the file, and then closes the file.
It takes in any IEnumerable<string> and adds every line to the specified file. So it always adds the line on a new line.
Small example:
const string originalFile = #"D:\Temp\file.txt";
const string newFile = #"D:\Temp\newFile.txt";
// Retrieve all lines from the file.
string[] linesFromFile = File.ReadAllLines(originalFile);
List<string> linesToAppend = new List<string>();
foreach (string line in linesFromFile)
{
// 1. Split the line at the semicolon.
// 2. Take the first index, because the first part is your required result.
// 3. Trim the trailing and leading spaces.
string appendAbleLine = line.Split(';').FirstOrDefault().Trim();
// Add the line to the list of lines to append.
linesToAppend.Add(appendAbleLine);
}
// Append all lines to the file.
File.AppendAllLines(newFile, linesToAppend);
Output:
Name- Harley Brown
Age- 20
You could even change the foreach-loop into a LINQ-expression, if you prefer LINQ:
List<string> linesToAppend = linesFromFile.Select(line => line.Split(';').FirstOrDefault().Trim()).ToList();
Why use char by char comparison when .NET Framework is full of useful string manipulation functions?
Also, don't use a file write function multiple times when you can use it only one time, it's time and resources consuming!
StreamReader stream = new StreamReader("file1.txt");
string str = "";
while ((string line = infile.ReadLine()) != null) { // Get every line of the file.
line = line.Split(';')[0].Trim(); // Remove comment (right part of ;) and useless white characters.
str += line + "\n"; // Add it to our final file contents.
}
File.WriteAllText("file2.txt", str); // Write it to the new file.
You could do this with LINQ, System.File.ReadLines(string), and System.File.WriteAllLines(string, IEnumerable<string>). You could also use System.File.AppendAllLines(string, IEnumerable<string>) in a find-and-replace fashion if that was, in fact, the functionality you were going for. The difference, as the names suggest, is whether it writes everything out as a new file or if it just appends to an existing one.
System.IO.File.WriteAllLines(newPath, System.IO.File.ReadLines(oldPath).Select(c =>
{
int semicolon = c.IndexOf(';');
if (semicolon > -1)
return c.Remove(semicolon);
else
return c;
}));
In case you aren't super familiar with LINQ syntax, the idea here is to loop through each line in the file, and if it contains a semicolon (that is, IndexOf returns something that is over -1) we cut that off, and otherwise, we just return the string. Then we write all of those to the file. The StreamReader equivalent to this would be:
using (StreamReader reader = new StreamReader(oldPath))
using (StreamWriter writer = new StreamWriter(newPath))
{
string line;
while ((line = reader.ReadLine()) != null)
{
int semicolon = line.IndexOf(';');
if (semicolon > -1)
line = c.Remove(semicolon);
writer.WriteLine(line);
}
}
Although, of course, this would feed an extra empty line at the end and the LINQ version wouldn't (as far as I know, it occurs to me that I'm not one hundred percent sure on that, but if someone reading this does know I would appreciate a comment).
Another important thing to note, just looking at your original file, you might want to add in some Trim calls, since it looks like you can have spaces before your semicolons, and I don't imagine you want those copied through.

how to replace a character in a string and save into text file in c#

I'm trying to replace pipe symbol(|) with new line(\n) in my text(test1.txt) file. But when I'm trying to save it in text(test2.text) file the result is not coming in my test2.txt file but I see the result in my console window. Any one please help on this.
string lines = File.ReadAllText(#"C:\NetProject\Nag Assignments\hi.txt");
//string input = "abcd|efghijk|lmnopqrstuvwxyz";
lines = lines.Replace('|', '\n');
File.WriteAllText(#"C:\NetProject\Nag Assignments\hi2.txt", lines);
Console.WriteLine(lines);
You can try this one:
lines = lines.Replace("|", Environment.NewLine);
It returns "\r\n", for non-Unix platforms according to documentation.
Seems like you want multiple things here. (both original question and subsequent comments)
One is to separate the lines and be able to reference them separately:
string[] separatedLines = lines.Split('|');
The other is to join them back together with a different separator:
string rejoinedLines = string.Join(Environment.NewLine, separatedLines);
You then have access to the individual lines from the separatedLines variable above such as separatedLines[0] and you can also write the rejoinedLines variable back to the other file like you wanted.
EDIT: For example, the following code:
string lines = "a|bc|def";
string[] separatedLines = lines.Split('|');
string rejoinedLines = string.Join(Environment.NewLine, separatedLines);
for (int i = 0; i < separatedLines.Length; i++)
{
Console.WriteLine("Line {0}: {1}", i + 1, separatedLines[i]);
}
Gives output of:
Line 1: a
Line 2: bc
Line 3: def
Instead of:
lines = lines.Replace('|', '\n');
Try:
lines = lines.Replace("|","\r\n");
string[] space = lines.Split ('|');
Will save every substring in space.
The line break should be \r\n for carriage return. It depends if you are reading a file binary or text mode. \n is used in text mode while \r\n is used in binary mode.

reading a CSV issue

I am trying to read a csv
following is the sample.
"0734306547 ","9780734306548 ","Jane Eyre Pink PP ","Bronte Charlotte ","FRONT LIST",20/03/2013 0:00:00,0,"PAPERBACK","Y","Pen"
Here is the code i am using read CSV
public void readCSV()
{
StreamReader reader = new StreamReader(File.OpenRead(#"C:\abc\21-08-2013\PNZdatafeed.csv"),Encoding.ASCII);
List<string> ISBN = new List<String>();
while (!reader.EndOfStream)
{
string line = reader.ReadLine();
if (!String.IsNullOrWhiteSpace(line))
{
string[] values = line.Split(',');
if (values[9] == "Pen")
{
ISBN.Add(values[1]);
}
}
}
MessageBox.Show(ISBN.Count().ToString());
}
I am not able to compare it values if (values[9] == "Pen") because when i debug the code it says values[9] value is \"Pen\""
How do i get rid of the special characters.?
The problem here is that you're splitting the line every time you find , and leaving the data like that. For example, if this is the line you're reading in:
"A","B","C"
and you split it at commas, you'll get "A", "B", and "C" as your data. According to your description, you don't want quotes around the data.
To throw away quotes around a string:
Check if the leftmost character is ".
If so, check if the rightmost character is ".
If so, remove the leftmost and rightmost characters.
In pseudocode:
if (data.left(1) == "\"" && data.right(1) == "\"") {
data = data.trimleft(1).trimright(1)
}
At this point you might have a few questions (I'm not sure how much experience you have). If any of these apply to you, feel free to ask them, and I'll explain further.
What does "\"" mean?
How do I extract the leftmost/rightmost character of a string?
How do I extract the middle of a string?

How can I remove a last part of a string with an unknown int?

So, I'm making a file transfer program from one PC in my house to the other. The client can look through the server's files and take what it wants. (Makes it very easy for moving projects/documents/music). This is an example of what a string of a file looks like:
New Text Document.txt : "(FILE)-(" + f.Length + " Bytes)"
My problem is removing : "(FILE)-(" + f.Length + " Bytes)".
How can I remove JUST that part from the string? Where the f.Length is unknown...
Thanks!
Just as an alternative to the regex answers, one option is to use LastIndexOf to find the last occurence of a known part of the string (e.g. (FILE)).
var oldString = "ThisIsAString (FILE)-(1234 Bytes";
int indexToRemoveTo = oldString.LastIndexOf("(FILE)");
// Get all the characters from the start of the string to "(FILE)"
var newString = oldString.Substring(0, indexToRemoveTo);
I hope I've got what you want
string contents = "some text (FILE)-(5435 Bytes) another text";
string result = Regex.Replace(contents, #"\(FILE\)-\(\d+ Bytes\)", "");
Console.WriteLine (result);
Prints:
some text another text
Solution to remove everything after .txt
string contents = "some text .txt (FILE)-(5435 Bytes) another text";
string lastSegment = ".txt";
var result = contents.Substring(0, contents.IndexOf(lastSegment) + lastSegment.Length);
Console.WriteLine (result);
prints some text .txt
var match = Regex.Match(pattern: #"\((.*)\)-\(\d+ Bytes\)$", input: name);
if(match.Success)
{
string fileName = match.Groups[1].Value;
}

Categories

Resources