Since I have not been able to find an resolution via my searching endeavor, I believe I may have a unique problem. Essentially I am creating a gene finding/creation application in c#.NET for my wife and am using RichTextBoxes for her to be able to highlight, color, export, etc the information she needs. I have made several custom methods for it because, as I am sure we all know, RichTextBoxes from Microsoft leave much to the imagination.
Anyway, here is my issue: I need to be able to search for a term across hard returns. The users have strings in 60 letter intervals and they need to search for items that may cross that hard return barrier. For instance let's say I have 2 lines (I will make them short for simplicity):
AAATTTCCCGGG
TTTCCCGGGAAA
If the user runs a search for GGGTTT, I need to be able to pull the result even though there is a line break/hard return in there. For the life of me I cannot think of a good way to do this and still select the result in the RichTextBox. I can always find the result but getting a proper index for the RichTextBox is what eludes me.
If needed I am not against richTextBox.SaveFile() and LoadFile() and parsing the rtf text as a string manually. It doesnt have to be pretty, in this case, it just has to work.
I appreciate any help/guidance you may give.
Here is a relevant snippet:
//textbox 2 search area (examination area)
private void button5_Click(object sender, EventArgs e)
{
textBox3.Text = textBox3.Text.ToUpper();
if (textBox3.Text.Length > 0)
{
List<string> lines = richTextBox2.Lines.ToList();
string allText = "";
foreach (string line in lines)
allText = allText + line.Replace("\r", "").Replace("\n", "");
if (findMultiLineRTB2(allText, textBox3.Text) != -1)
{
richTextBox2.Select(lastMatchForRTB2, textBox3.Text.Length);
richTextBox2.SelectionColor = System.Drawing.Color.White;
richTextBox2.SelectionBackColor = System.Drawing.Color.Blue;
}//end if
else
MessageBox.Show("Reached the end of the sequence", "Finished Searching");
}//end if
}//end method
private int findMultiLineRTB2(string rtbText, string searchString)
{
lastMatchForRTB2 = rtbText.IndexOf(searchString, lastMatchForRTB2 + 1);
return lastMatchForRTB2;
}
So i make an assumption: you want to search a word across all lines where each line is 60 characters long. The desired result is the index of that word.
You just have to build a string that has no line breaks, for example with string.Join:
string allText = string.Join("", richTextBox.Lines);
int indexOf = allText.IndexOf("GGGTTT"); // 9 in your sample
Related
Alright, so I'm writing an application that needs to be able to extract a VAT-Number from an invoice (https://en.wikipedia.org/wiki/VAT_identification_number)
The biggest challenge to overcome here is that as apparent from the wikipedia article I have linked to, each country uses its own format for these VAT-numbers (The Netherlands uses a 14 character number while Germany uses a 11 character number).
In order to extract these numbers, I throw every line from the invoice into an array of strings, and for each string I test if it has a length that is equal to one of the VAT formats, and if that checks out, I check if said string also contains a country code ("NL", "DE", etc).
string[] ProcessedFile = Reader.ProcessFile(Input);
foreach(string S in ProcessedFile)
{
RtBEditor.AppendText(S + "\n");
}
foreach(string X in ProcessedFile)
{
string S = X.Replace(" ", string.Empty);
if (S.Length == 7)
{
if (S.Contains("GBGD"))
{
MessageBox.Show("Land = Groot Britanie (Regering)");
}
}
/*
repeat for all other lenghts and country codes.
*/
The problem with this code is that 1st:
if there is a string that happens to have the same length as one of the VAT-formats, and it has a country code embedded in it, the code will incorrectly think that it has found the VAT-number.
2nd:
In some cases, the VAT-number will be included like "VAT-number: [VAT-number]". In this case, the text that precedes the actual number will be added to its length, making the program unable to detect the actual VAT-Number.
The best way to fix this is in my assumption to somehow isolate the VAT-Number from the strings all together, but I have yet to find a way how to actually do this.
Does anyone by any chance know any potential solution?
Many thanks in advance!
EDIT:
Added a dummy invoice to clarify what kind of data is contained within the invoices.
As someone in the comments had pointed out, the best way to fix this is by using Regex. After trying around a bit I came to the following solution:
public Regex FilterNormaal = new Regex(#"[A-Z]{2}(\d)+B?\d*");
private void BtnUitlezen_Click(object sender, EventArgs e)
{
RtBEditor.Clear();
/*
Temp dummy vatcodes for initial testing.
*/
Form1.Dummy1.VAT = "NL855291886B01";
Form1.Dummy2.VAT = "DE483270846";
Form1.Dummy3.VAT = "SE482167803501";
OCR Reader = new OCR();
/*
Grab and process image
*/
if(openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
Input = new Bitmap(openFileDialog1.FileName);
}
catch
{
MessageBox.Show("Please open an image file.");
}
}
string[] ProcessedFile = Reader.ProcessFile(Input);
foreach(string S in ProcessedFile)
{
string X = S.Replace(" ", string.Empty);
RtBEditor.AppendText(X + "\n");
}
foreach (Match M in FilterNormaal.Matches(RtBEditor.Text))
{
MessageBox.Show(M.Value);
}
}
At first, I attempted to iterate through my array of strings to find a match, but for reasons unknown, this did not yield any results. When applying the regex to the entire textbox, it did output the results I needed.
I'm working on my own basic syntax highlight editor in C#. I've already completed the automatic coloring of keywords, functions etc etc. I don't need any other fancy stuff like automatic code indentation.
However, I do wish to have a code minify / maxify button. Nothing fancy. I just want it to automaticly set a newline before any opening bracket and one behind it with either tab characters or changing the SelectionIndent Property.
So something like this:
test { test { test } test }
Becomes:
test
{
test
{
test
}
}
And of course the minify button should do the exact opposite, putting everything on 1 line.
I've already tried working with the Regex.Replace Method. I didn't quite get it to work, but thinking about that approach, it would cause issues if the opening and closing brackets get mixed up. Anyway, this is what I had untill I gave up and decided to ask you guys for some help:
string tabs = "";
private void btnMax_Click(object sender, EventArgs e)
{
var count = codeRichTextBox.Text.Count(x => x == '{');
for(int i=1; i<= count; i++)
{
// The idea was to add \t to tabs here on each iteration
}
string pattern = "{";
string replacement = "\n{\n\t";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(codeRichTextBox.Text, replacement);
codeRichTextBox.Text = result;
}
Obviously that solution is the wrong approach and isn't going to work. So what should I do instead?
Edit: Although it would be nice, it doesn't have to take into account that part of the string already has code indentation. The maxify button only needs to work on a string that's on a single line.
My idea: You'll need to parse the text, counting the current nesting level of { and } .
For each { or } found, decide on the proper whitespace-string-before (prefix) and whitespace-string-after (suffix) based on the current nesting level (for example just \n { \n for the first level).
See if the desired prefix is already there. If not, delete any existing whitespace then add the prefix. Do the same for the suffix.
I'm having difficulty creating a code that able to pick up specific words and color them.
I'm currently using this code:
private void Colorize(string word, Color color, int startIndex)
{
if (this.richTextBox1.Text.Contains(word))
{
int index = -1;
int selectStart = this.richTextBox1.SelectionStart;
while ((index = this.richTextBox1.Text.IndexOf(word, (index + 1))) != -1)
{
this.richTextBox1.Select((index + startIndex), word.Length);
this.richTextBox1.SelectionColor = color;
this.richTextBox1.Select(selectStart, 0);
this.richTextBox1.SelectionFont = new Font(richTextBox1.Font, FontStyle.Regular);
this.richTextBox1.SelectionColor = Color.Black;
}
this.richTextBox1.SelectionColor = Color.Black;
}
}
The problem is that when the text of the RichTextBox is too large it hangs and runs from top to bottom, is there any way to instantly color keywords?
I'm doing a basic IDE, but I need some color java-based keywords.
Any error sorry I used the google translator.
You are aware that String.Contains does not check for words, aren't you?
If you use String.Contains("able"), then indeed you will find the word "able", but you'll also find words like "disabled", "sable" and "IEquatable".
To check for words you'll need a regular expression.
Whenever you need to process sequences of something, LINQ is your friend. Consider to familiarize yourself with the possibilities of LINQ.
Introduction of LINQ
Using Regular expressions and LINQ I could colorize the complete works of shakespeare (over five million characters) in about 5 seconds
// on load form: fill the rich text box with
// the complete works of William Shakespeare
private async void Form1_Load(object sender, EventArgs e)
{
const string completeShakespeare = "http://www.gutenberg.org/cache/epub/100/pg100.txt";
using (var downloader = new HttpClient())
{
this.richTextBox1.Text = await downloader.GetStringAsync (completeShakespeare);
}
}
// on button click: mark all "thee" red
private void button1_Click(object sender, EventArgs e)
{
var stopwatch = Stopwatch.StartNew();
this.Colorize2("thee", Color.Red);
var elapsed = stopwatch.Elapsed;
Debug.WriteLine ("Coloring a text with {0} characters took {1:F3} sec",
this.richTextBox1.Text.Length,
elapsed.TotalSeconds);
}
private void Colorize2(string word, Color color)
{
string regString = String.Format(#"\b{0}\b", word);
// regex: match substring that match word,
// with boundaries to non alphanumeric characters like space and \n \r \t
var regex = new Regex(regString, RegexOptions.IgnoreCase);
var matches = regex.Matches(richTextBox1.Text);
foreach (Match match in matches.Cast<Match>())
{
this.richTextBox1.Select(match.Index, match.Length);
this.richTextBox1.SelectionColor = color;
}
}
Once Iv'e needed to implement C#, Python and Matlab syntax highlighting so I've spent some time researching about it.
The problem with this Select method in RichTextBox is that the selection itself takes time since it also grafically select the text and when you want to dinamically color the syntax when the code is written there are many selections which makes it slow.
Trying to parse the modify the rtf is possible but is a real headache and requires you and the ones that will maintain the code after you to understand this format.
A good solution I've found is that there are many open sources implement a Control of their own for syntax highlighting which you acn use.
In FastColoredTextBox, the one I used, you can choose the language to highlight and the format in which you want it to be shown, you can also add your own language to that list and configure it to indent the hightlighted code automatically using Regex.
Sorry if this is not the answer you expected but this is exacly the type of thing to search for and not implement by yourself.
I have some data and I want to write them to a specific line in notepad using C#.
For example I have two textboxes and the data inside them are "123 Hello", for textBox1, and "565878 Hello2" for textBox2.
When I press SAVE button, those data will be saved into one file but with different line. I want to save the first data in the first line and the second data in the third line.
How can I do this?
This question is too broad. The simple answer is that you write the two lines to a file, but write a newline (either "\r\n" or Environment.NewLine) between each string. That will put the two strings on different lines. If you want the second string on the third line, then you should write two newlines between each string.
If neither of those are the answer, then you need to be a lot more specific about why not. Is the file empty to start with? What have you tried? Where, specifically, are you getting stuck? What platform?
And I really don't see what this has to do with NotePad.
EDIT:
You have clarified that you are starting with an existing text file and want to replace the content at the specified lines.
This is a more complex thing to do, and may be beyond your skills if you are just starting out. The basic approach is this:
Assuming you can read the entire file into memory, load the file into a string. You will have to parse new lines to find the lines you want to replace. You can then just replace those parts of the string with the new data. When finished, write the file back to disk.
If the file is too big to load into memory, then it becomes much more complex. I'm sorry, but since you've done such a poor job of describing the issue, I'm not going to the trouble of going over the details for this case. And such a task probably falls outside the scope of a stackoverflow answer any way.
If you line numbers are not fixed you can do something like below:
class Program
{
private static void Main()
{
var data = "";
const string data1 = "Data1";//First Data
const string data2 = "Data2";//Second Data
const int line1 = 1;//First Data Line
const int line2 = 3;//Second Data Line
var maxNoOfLines = Math.Max(line1, line2);
for (var i = 1; i <= maxNoOfLines; i++)
{
if (i == line1)
{
data += data1 + Environment.NewLine;
}
else if (i == line2)
{
data += data2 + Environment.NewLine;
}
else
{
data += Environment.NewLine;
}
}
File.WriteAllText(#"C:\NOBACKUP\test.txt", data);
}
}
Otherwise if line numbers are fixed it will be much more simpler. You can just remove the loop from above and hardcode the values.
My Goal: I want to parse a file and display it in a textbox. Here's the code (thanks to Aviral Singh).
private void Form1_Load(object sender, EventArgs e)
{
var path = #"C:\Users\Smith\Desktop\Settings.txt"; //Path to settings file.
RichTextBox rtb = new RichTextBox();
System.IO.StreamReader sis = new System.IO.StreamReader(path);
rtb.Text = sis.ReadToEnd();
sis.Close();
foreach (string line in rtb.Lines)
{
if (line.Contains("Installation Technical Manual:") == true)
{
string numbers = line.Substring(line.IndexOf("Installation Technical Manual:"));
textBox1.Text = numbers;
}
}
}
Text file looks like this:
My Problem: The textbox in my program displays entire line: Installation Technical Manual: (1234567890).
I just want the number with brackets (1234567890). to be displayed in the textbox. What changes should I make to the code to remove the words and just display numbers with brackets around it? Thanks for your help. :)
numbers = "(" + new String(numbers.Where(Char.IsDigit).ToArray()) + ")";
The problem is that IndexOf() is going to give you the starting position of the string which you're asking for the index of. Which in your example is going to be 0, so a Substring call that starts at 0 is going to return you the entire string.
What you really want to do is Substring(IndexOf("Installation Technical Manual:") + "Installation Technical Manual:".Length). That will give you whatever comes after your string.
Assuming you have ':' in your line always,
if(line.Contains(":"))
{
string numbers = line.Split(':')[1];
textBox1.Text = numbers;
}
The reason your code is not working as you have used the substring method as with one parameter, so it is used as :
public string Substring(
int startIndex
)
See: http://msdn.microsoft.com/en-us/library/hxthx5h6.aspx
And you are passing in, line.IndexOf("Installation Technical Manual:")
which will return ).
See here: http://msdn.microsoft.com/en-us/library/k8b1470s.aspx
So you are essentially saying return Substring of string Installation Technical Manual:(number) starting at 0 which basically returns the whole line.