How can I delete words from a "string" in the RichTextBox.
Example:
[02/04/2014 17:04:21] Thread 1 Banned: xxxxxxxxx#xxxx.tld
[02/04/2014 17:04:21] Thread 2: Banned: xxxxxxxxx#xxxx.tld
[02/04/2014 17:04:21] Thread 3: Banned: xxxxxxxxx#xxxx.tld
[02/04/2014 17:04:21] Thread 4: Banned: xxxxxxxxx#xxxx.tld
I would like to delete all rows with the word "Banned" in the line.
How can I do this?
Thanks in advance.
You can use LINQ to remove all the lines that contains the work "Banned":
richTextBox1.Lines = richTextBox1.Lines
.Where((line, b) => !line.Contains("Banned"))
.Select((line, b) => line).ToArray();
I know this method looks ugly. But, if you don't want to remove formatting from the existing text in the richtextbox then you should use this method. This example is not tested but, you can get logic from here.
for (int iLine = 0; iLine < rtf.Lines.Length; iLine++)
{
if (rtf.Lines[iLine].Contains("Banned"))
{
int iIndex = rtf.Text.IndexOf(rtf.Lines[iLine]);
rtf.SelectionStart = iIndex;
rtf.SelectionLength = rtf.Lines[iLine].Length;
rtf.SelectedText = string.Empty;
iLine--; //-- is beacause you are removing a line from the Lines array.
}
}
You could try use the answer from this post - I would adjust the code slightly to neaten it up a bit.
URL:
what is the best way to remove words from richtextbox?
Code snippet from the URL (which would need to be tidied up).
string[] lines = richTextBox1.Lines;
List<string> linesToAdd = new List<string>();
string filterString = "Banned".";
foreach (string s in lines)
{
string temp = s;
if (s.Contains(filterString))
temp = s.Replace(filterString, string.Empty);
linesToAdd.Add(temp);
}
richTextBox1.Lines = linesToAdd.ToArray();
I would adjust the above code and whilst still using the loop, just check if the line contains the word you looking for "Banned" and then remove the line / do what is need with it.
I hope this helps?
Related
I am an amateur in coding and I'm struggling with a simple problem. I need to remove the numeration in the .srt file, but I couldn't find the correct regex, using regex might be a bad idea, because the subtitle itself can contain a number, I was thinking about matching "-->" and then removing the previous line, but I couldn't do it. Can someone help me?
I need to remove the following lines (numeration)
screenshot
UPDATE
I came up with the following code, which replaces numbers with spaces, but it doesn't delete the line, as I want
var source = File.ReadAllLines("C:\\Users\\name\\Desktop\\temp1\\Doctor.Strange.2016.720p.BluRay.x264.[YTS.MX]-English.srt");
var newFile = #"C:\Users\name\Desktop\temp1\new.srt";
for (int i = 0; i < source.Length; i++)
{
if (source[i].Contains(matchSymbol))
{
source[i - 1] = "";
}
}
File.WriteAllLines(newFile, source);
If the file is not super large, a better way would be to read every line of the file and check each line with Int32.TryParse(). If True is returned for that line, skip it, otherwise write the contents of the line to an output file.
Something like this should work:
void RemoveNumberLines()
{
var source = File.ReadAllLines("C:\\Users\\name\\Desktop\\temp1\\Doctor.Strange.2016.720p.BluRay.x264.[YTS.MX]-English.srt");
var newFile = #"C:\Users\name\Desktop\temp1\new.srt";
var matchSymbol = "-->";
var myNewFile = new List<string>(); bool addPrevious = true; string previous = "";
foreach (var item in source)
{
addPrevious = !item.Contains(matchSymbol);
if (addPrevious)
{
myNewFile.Add(previous);
}
previous = item;
}
if (addPrevious)
{
myNewFile.Add(previous);
}
File.WriteAllLines(newFile, myNewFile);
}
Adding the previous line, if the active line won't contain "-->".
So in this example I attempted to make a program that inserts a "*" in between every character that is in a certain textbox (textBox1). Though I'm having trouble figuring it out. Yes I have looked around on stack-overflow already, nothing seems to relate/work with what I'm trying to do.
Here's the code I have currently:
for (int i = 1; i <= textBox1.Text.Length; i += 1)
{
textBox2.Text = textBox1.Text.Insert(i, "*");
i++;
}
Here is a picture of what this current code does:
pretty easy to do like...
textBox2.Text = string.Join('*', textBox1.Text.ToCharArray())
You're doing a whole lot of unnecessary things. I'm using two strings instead of text boxes as I'm on Console, but the idea is the same.
var tb1Text = "hello";
var tb2Text = string.Empty;
foreach (var ch in tb1Text)
{
tb2Text += ch + "*";
}
tb2Text = tb2Text.TrimEnd(new char[] { '*' });
We iterate through the string (because a string is essentially an array of char), and add it to the tb2Text along with a trailing *. If you don't want a trailing * at the very end, use the last line of code, otherwise get rid of it.
Result
tb1Text = hello
And
tb2Text = h*e*l*l*o
Is there a way to selectively replace XElement content with other XElements?
I have this XML:
<prompt>
There is something I want to tell you.[pause=3]
You are my favorite caller today.[pause=1]
Have a great day!
</prompt>
And I want to render it as this:
<prompt>
There is something I want to tell you.<break time="3s"/>
You are my favorite caller today.<break time="1s"/>
Have a great day!
</prompt>
I need to replace the placeholders with actual XElements, but when I try to alter the content of an XElement, .NET of course escapes all of the angle brackets. I understand why the content would normally need to be correctly escaped, but I need to bypass that behavior and inject XML directly into content.
Here's my code that would otherwise work.
MatchCollection matches = Regex.Matches(content, #"\[(\w+)=(\d+)]");
foreach (XElement element in voiceXmlDocument.Descendants("prompt"))
{
if (matches[0] == null)
continue;
element.Value = element.Value.Replace(matches[0].Value, #"<break time=""5s""/>");
}
This is a work in progress, so don't worry so much about the validity of the RegEx pattern, as I will work that out later to match several conditions. This is proof of concept code and the focus is on replacing the placeholders as described. I only included the iteration and RegEx code here to illustrate that I need to be able to do this to a whole document that is already populated with content.
You can use XElement.Parse() method:
First, get the outer xml of your XElement, for example,
string outerXml = element.ToString();
The you have exactly this string to work with:
<prompt>
There is something I want to tell you.[pause=3]
You are my favorite caller today.[pause=1]
Have a great day!
</prompt>
Then you can do your replacement
outerXml = outerXml.Replace(matches[0].Value, #"<break time=""5s""/>");
Then you can parse it back:
XElement repElement = XElement.Parse(outerXml);
And, finally, replace original XElement:
element.ReplaceWith(repElement);
The key to all of this is the XText, which allows you to work with text as an element.
This is the loop:
foreach (XElement prompt in voiceXmlDocument.Descendants("prompt"))
{
string text = prompt.Value;
prompt.RemoveAll();
foreach (string phrase in text.Split('['))
{
string[] parts = phrase.Split(']');
if (parts.Length > 1)
{
string[] pause = parts[0].Split('=');
prompt.Add(new XElement("break", new XAttribute("time", pause[1])));
// add a + "s" if you REALLY want it, but then you have to get rid
// of it later in some other code.
}
prompt.Add(new XText(parts[parts.Length - 1]));
}
}
This is the end result
<prompt>
There is something I want to tell you.<break time="3" />
You are my favorite caller today.<break time="1" />
Have a great day!
</prompt>
class Program
{
static void Main(string[] args)
{
var xml =
#"<prompt>There is something I want to tell you.[pause=3] You are my favorite caller today.[pause=1] Have a great day!</prompt>";
var voiceXmlDocument = XElement.Parse(xml);
var pattern = new Regex(#"\[(\w+)=(\d+)]");
foreach (var element in voiceXmlDocument.DescendantsAndSelf("prompt"))
{
var matches = pattern.Matches(element.Value);
foreach (var match in matches)
{
var matchValue = match.ToString();
var number = Regex.Match(matchValue, #"\d+").Value;
var newValue = string.Format(#"<break time=""{0}""/>", number);
element.Value = element.Value.Replace(matchValue, newValue);
}
}
Console.WriteLine(voiceXmlDocument.ToString());
}
}
Oh, my goodness, you guys were quicker than I expected! So, thanks for that, however in the meantime, I solved it a slightly different way. The code here looks expanded from before because once I got it working, I added some specifics into this particular condition:
foreach (XElement element in voiceXmlDocument.Descendants("prompt").ToArray())
{
// convert the element to a string and see to see if there are any instances
// of pause placeholders in it
string elementAsString = element.ToString();
MatchCollection matches = Regex.Matches(elementAsString, #"\[pause=(\d+)]");
if (matches == null || matches.Count == 0)
continue;
// if there were no matches or an empty set, move on to the next one
// iterate through the indexed matches
for (int i = 0; i < matches.Count; i++)
{
int pauseValue = 0; // capture the original pause value specified by the user
int pauseMilliSeconds = 1000; // if things go wrong, use a 1 second default
if (matches[i].Groups.Count == 2) // the value is expected to be in the second group
{
// if the value could be parsed to an integer, convert it from 1/8 seconds to milliseconds
if (int.TryParse(matches[i].Groups[1].Value, out pauseValue))
pauseMilliSeconds = pauseValue * 125;
}
// replace the specific match with the new <break> tag content
elementAsString = elementAsString.Replace(matches[i].Value, string.Format(#"<break time=""{0}ms""/>", pauseMilliSeconds));
}
// finally replace the element by parsing
element.ReplaceWith(XElement.Parse(elementAsString));
}
Oh, my goodness, you guys were quicker than I expected!
Doh! Might as well post my solution anyway!
foreach (var element in xml.Descendants("prompt"))
{
Queue<string> pauses = new Queue<string>(Regex.Matches(element.Value, #"\[pause *= *\d+\]")
.Cast<Match>()
.Select(m => m.Value));
Queue<string> text = new Queue<string>(element.Value.Split(pauses.ToArray(), StringSplitOptions.None));
element.RemoveAll();
while (text.Any())
{
element.Add(new XText(text.Dequeue()));
if (pauses.Any())
element.Add(new XElement("break", new XAttribute("time", Regex.Match(pauses.Dequeue(), #"\d+"))));
}
}
For every prompt element, Regex match all your pauses and put them in a queue.
Then use these prompts to delimit the inner text and grab the 'other' text and put that in a queue.
Clear all data from the element using RemoveAll and then iterate over your delimited data and re-add it as the appropriate data type. When you are adding in the new attributes you can use Regex to get the number value out of the original match.
im trying to make a code that searches through a textfile for a certain phrase and then populates a textbox with the line if a phrase occurs in that. There are no errors with this code, but it doesn't work at all. Anyone know what is wrong? I'm not too sure if what i'm doing is remotely correct.
{
tuitDisplayTextBox.Text = "";
string[] tuitFilePath = File.ReadAllLines(Server.MapPath("~") +"/App_Data/tuitterMessages.txt");
for (int i = 0; i < tuitFilePath.Length; i++)
{
if (tuitFilePath[i].Contains(searchTextBox.Text))
{
tuitDisplayTextBox.Text += tuitFilePath[i];
}
}
Your solution should work... for the last line that matches, and only that one.
LINQ can help you here, though. Here's a solution that should work.
tuitDisplayTextBox.Text =
File.ReadLines(Server.MapPath("~") +"/App_Data/tuitterMessages.txt")
.Where(n => n.Contains(searchTextBox.Text)).Aggregate((a, b) =>
a + Enviroment.NewLine + b);
Here, what it does is it reads the lines of the file into an IEnumerable<string>, and then I filter that with the Where method, which basically means "if the condition is true for this element, add this element to the list of things to return, else don't add it". And then Aggregate is a bit more complicated. Basically what it does is it takes the first two items from the collection, and then pass a lambda through them that returns a value. Then call the lambda again with that result and the third element. And then it takes that result and calls it with the fourth element. And so on.
Here's some code more similar to yours that will also work:
tuitDisplayTextBox.Text = "";
IEnumerable<string> lines =
File.ReadAllLines(Server.MapPath("~") +"/App_Data/tuitterMessages.txt");
StringBuilder sb = new StringBuilder
foreach (string line in lines)
{
if (line.Contains(searchTextBox.Text))
{
sb.AppendLine(line);
}
}
tuitDisplayTextBox.Text = sb.ToString();
Here it's a bit different. First it reads all the lines into an IEnumerable<string> called lines. Then it makes a StringBuilder object (basically a mutable string). After that, it foreaches the lines in the IEnumerable<string> (I thought it was more appropriate here) and then if the line contains the text you want, it adds that line and a newline to the StringBuilder object. After that, it sets your textbox's text to the result of all of that, by getting the string representation of the StringBuilder instance.
And if you really want a for loop, here's the code modified to use a for loop:
tuitDisplayTextBox.Text = "";
string[] lines =
File.ReadAllLines(Server.MapPath("~") +"/App_Data/tuitterMessages.txt");
StringBuilder sb = new StringBuilder
for (int i = 0; i < lines.Length; i++)
{
if (lines[i].Contains(searchTextBox.Text))
{
sb.AppendLine(lines[i]);
}
}
tuitDisplayTextBox.Text = sb.ToString();
Please note that File.ReadAllLines break sentences at '\r' or '\n'.
So, if you search for "hello world" and this text is break in the file into 2 lines (e.g. "... hello /n world" your code will failed...
So, use the ReadAllText() instead, return one string contains all file's text.
Still, you might face sometimes problems with file encoding, but this is another issue.
After, and if, you find the text you are searching for you can use the ReadAllLines to decide about the location of the text.
I am very new to C#. I learn best by experimentation, but of course, I will get completely stumped sometimes. I will try to explain my problem the best I can with what knowledge of the programming language I currently have.
I have been trying to create a simple tool to edit/add lines of text into a text file. I have done much researching, especially on this site, and all the information has been extremely helpful. My problem though, is adding text to both sides to a single line of text within a multi-line textbox.
So lets say I have a textbox with 2 existing lines; I want to add some text next to both sides of to one of one lines, and do the same to the next one. Here is an example of what the text would look like before and after a button is hit:
Before
is not the same as is different than
After
A is not the same as B A is different than B
The two lines in "Before" would be in textBox1 (multiline), and would be inserted to richTextBox1 as "After".
Hopefully I have explained it clearly enough, I do not know where to begin with this.
Thank you.
If you know which index you have to update the text, then you should be able to inset the value directly using insert function exposed by string class
Example:
//Get the text box value
var formatedTextboxString = this.textbox1.Text;
formatedTextboxString = formatedTextboxString.Insert(0, "A ");
formatedTextboxString = formatedTextboxString.Insert(21, "B");
//Place the formated text back to the richTextBox
this.richTextBox1.Text = formatedTextboxString;
Try
"{0} is not the same as {1} {2} is different than {3}"
In textbox1. Then use:
textbox2.Text = String.Format(textbox1.Text, A, B, A, B);
In case if you have multiline textbox:
var list = new List<string>(textBox1.Lines);
for (int i = 0; i < list.Count; ++i)
{
list[i] = "A" + list[i] + "B";
}
textBox1.Lines = list.ToArray();
string[] arr = textBox1.Text.Split(Environment.Newline);
//then loop over each line and add whatever you want :-
foreach (string s in arr)
{
//add here
}
I guess this is good enough hint to start with :)