I have a search function that searches keywords in a block of text and displays a truncated version of the results. My problem is that it will not show the searched keyword if its near the end.
For example.
Text = "A block of text is text that is grouped together in some way, such as with the use of paragraphs or blockquotes on a Web page. Often times, the text takes on the shape of a square or rectangular block"
I search for "times" with
text = text.Substring(0, 100) + "...";
It will return
"A block of text is text that is grouped together in some way, such as with the use of paragraphs or..."
Is there a way to return 100 characters before and after the searched keyword?
You can do this,
string s = "A block of text is text that is grouped together in some way, such as with the use of paragraphs or";
string toBeSearched = "grouped";
int firstfound = s.IndexOf(toBeSearched);
if (firstfound != -1 )
{
string before = s.Substring(0 , firstfound);
string after = s.Substring(firstfound + toBeSearched.Length);
}
DEMO
string s = "A block of text is text that is grouped together in some way, such as with the use of paragraphs or";
string wordtoSearch = "block";
int firstfound = s.IndexOf(wordtoSearch);
// If the index of the first letter found is greater than 100, get the 100 letters before the found word and 100 letters after the found word
if (firstfound > 100)
{
string before = s.Substring(firstfound , firstfound-100);
string after = s.Substring(firstfound + wordtoSearch.Length, 100);
Console.WriteLine(before);
Console.WriteLine(after);
}
//// If the index of the first letter found is less than 100, get the letters before the found word and 100 letters after the found word
if(firstfound < 100)
{
string before = s.Substring(0, firstfound);
Console.WriteLine(before);
if(s.Length >100)
{
string after = s.Substring(firstfound + wordtoSearch.Length, 100);
Console.WriteLine(after);
}
else
{
string after = s.Substring(firstfound + wordtoSearch.Length);
Console.WriteLine(after);
}
}
You can do something like this as well, making it a bit more reusable and able to match multiple instances of the keyword
string input = "A block of text is text that is grouped together in some way, such as with the use of paragraphs or blockquotes on a Web page. Often times, the text takes on the shape of a square or rectangular block";
int buffer = 30; // how much do you want to show before/after
string match = "times";
int location = input.IndexOf(match);
while (location != -1) {
// take buffer before and after:
int start = location - Math.Min (buffer , location); // don't take before start
int end = location + match.Length
+ Math.Min( buffer, input.Length - location - match.Length); // don't take after end
Console.WriteLine("..." + input.Substring(start, end-start) + "...");
location = input.IndexOf(match,location+1);
}
Giving you an output of
...A block of text is text that is gro...
...with the use of paragraphs or blockquotes on a Web page. Often ...
...pe of a square or rectangular block...
Related
I have a list of string where one item is like, textItem1 = "Brown, Adam. (user)(admin)(Sales)" where I would always have to extract the text from the last pair of parentheses, which in this case will be Sales.
I tried the following:
string name = DDlistName.SelectedItem.ToString();
int start = name.IndexOf("(");
int end = name.IndexOf("(");
string result = name.Substring(start + 1, end - start - 1);
_UILabelPrintName.Text = result;
Problem: This always picks the text from first pair of parentheses, which in this case user.
Reading lots of similar question's answer I realised Regex might not be recommended in this case (not particularly succeeded either trying other codes). However any help with any short routine which can do the task will be really appreciated.
You need to use LastIndexOf instead of IndexOf, and check for a close parenthesis at the end.
string name = "Brown, Adam. (user)(admin)(Sales)";
int start = name.LastIndexOf("(");
int end = name.LastIndexOf(")");
string result = name.Substring(start + 1, end - start - 1);
Really you'd want to validate start and end to be sure that both parenthesis were found. LastIndexOf returns -1 if the character is not found.
And in order to handle nesting we need to search forward for the closing parenthesis after the location of the opening parenthesis.
string name = "Brown, Adam. (user)(admin)((Sales))";
int start = name.LastIndexOf('(');
int end = (start >= 0) ? name.IndexOf(')', start) : -1;
string result = (end >= 0) ? name.Substring(start + 1, end - start - 1) : "";
You can use the split function, breaking the string at the opening parenthesis. The last array element is the desired output with a tailing ")", which will then be removed.
var input = "Brown, Adam. (user)(admin)(Sales)";
// var input = DDlistName.SelectedItem.ToString();
var lastPick = input.Split(new[] { "(" }, StringSplitOptions.RemoveEmptyEntries).Last();
var output = lastPick.Substring(0, lastPick.Length - 1);
_UILabelPrintName.Text = output;
Another approach is to use a while loop with IndexOf. It cuts the input string as long as another "(" is found. If not more "(" are found, it takes the contents of the remaining string until the closing parenthesis ")":
int current = -1;
while(name.IndexOf("(") > 0)
{
name = name.Substring(name.IndexOf("(") + 1);
}
var end = name.IndexOf(")");
var output = name.Substring(0, end);
_UILabelPrintName.Text = output;
Or use LastIndexOf....
I want to split a string into an array at a point where the text wraps for a given width
Suppose this is the string.
I want text width to be 300 :
I want to split a string into an array at a point where the text wraps for a given width
And use a function, something like this :
Text.SplitAtWrap(300,Text)
This is the output i want :
(0) I want to split a string into an
(1) array at a point where the text
(2) wraps for a given width
Edit:
I would probably have to take the font into account, so probably have to use Drawing.Graphics.
There is an answer here (please give credit to whom deserve it)
public List<string> GetSubstrings(string toSplit, int maxLength, Graphics graph, Font font)
{
List<string> substrings = new List<string>();
string[] words = toSplit.Split(" ".ToCharArray());
string oneSub = "";
foreach (string oneWord in words)
{
string temp = oneSub + oneWord + " ";
if (graph.MeasureString( temp, font).Width > maxLength)
{
substrings.Add(oneSub);
oneSub = oneWord + " ";
}
else
oneSub = temp;
}
substrings.Add(oneSub);
return substrings;
}
Basically, your input string is divided in its component words, then each word is measured using the graphics object and a reference font. If the length of the current word plus the previous words is less than the required length the word is rejoined together. Otherwise the resulting string is added to a list of strings to be returned to the caller.
Hi all i am doing an application where i write my data to the text file. What ever data that user enters on the form and click on save i will save that data to the text file that was chosen by the user . Assume my content is as follows
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
I would like to pad the next 8 lines with the following
9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999
Lie that if i have 5 lines of text in the file i would like to pad the next 5 lines with the same as mentioned can any one tell how to do this
Each and every line length is '94'
Any number of lines can be there
var text = "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234" + Environment.NewLine + "1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234";
const String padWith = "9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999";
const int lineNum = 10;
var lines = text.Split(new[] { Environment.NewLine }, StringSplitOptions.None).ToList();
while(lines.Count < lineNum) {
lines.Add(padWith);
}
File.WriteAllLines(path, lines);
Here goes the code.
1) Find out the no of lines in your file
2) make count%10, if count%10==0 do not pad else 10-result=required
length , Pad with required length.
Sample code assume you have 8 lines
int cnt = 8;
int result = cnt % 10; // Will get 8
int iresult1 = 10 - result;
Hope it helps
If I have a RichTextBox that is loaded from a file containg:
TEXT MORETEXT 10.505 100.994 0
TEXT MORETEXT -5.132 -12.994 90
TEXT MORETEXT 100.001 -8.994 270
and a TextBox that contains whatever the user enters in the textbox. Let's say the user enters "10.005".
My question is, how do I take this value and add it to the 3rd column containing the values 10.505, -5.132, 100.001. Once it is added, I would like to take the value and Replace the old value in the string. SO the updated RichTextBox would look like this.
TEXT MORETEXT 20.510 100.994 0
TEXT MORETEXT 4.873 -12.994 90
TEXT MORETEXT 110.006 -8.994 270
RIGHT NOW I am able to strip the strings from the RichTextBox by using this code:
private void calculateXAndYPlacementTwo()
{
// Reads the lines in the file to format.
var fileReader = File.OpenText(filePath);
// Creates a list for the lines to be stored in.
var fileList = new List<string>();
// Adds each line in the file to the list.
while (true)
{
var line = fileReader.ReadLine();
if (line == null)
break;
fileList.Add(line);
}
// Creates new lists to hold certain matches for each list.
var xyResult = new List<string>();
var xResult = new List<string>();
var yResult = new List<string>();
// Iterate over each line in the file and extract the x and y values
fileList.ForEach(line =>
{
Match xyMatch = Regex.Match(line, #"(?<x>-?\d+\.\d+)\s+(?<y>-?\d+\.\d+)");
if (xyMatch.Success)
{
// grab the x and y values from the regular expression match
String xValue = xyMatch.Groups["x"].Value;
String yValue = xyMatch.Groups["y"].Value;
// add these two values, separated by a space, to the "xyResult" list.
xyResult.Add(String.Join(" ", new[]{ xValue, yValue }));
// Adds the values into the xResult and yResult lists.
xResult.Add(xValue);
yResult.Add(yValue);
// Place the 'X' and 'Y' values into the proper RTB.
xRichTextBox.AppendText(xValue + "\n");
yRichTextBox.AppendText(yValue + "\n");
}
});
}
To get the values in the xRichTextBox looking like:
10.505
-5.132
100.001
and the yRichTextBox looking like:
100.994
-12.994
-8.994
But I do not know how to turn those into values that can have addition used on them...
EDIT:
I have messed around with this some more... I am now using this code (below) to try to accomplish what I need it to do. This is only for the "X" (3rd column).
HOWEVER THIS CODE IS NOT WORKING (it concats the user input to the end of the xRichTextBox instead of mathematically adding it to each line..)
The xDisplacementTextBox is the user input and the xRichTextBox is the stripped values from the main string.
StringBuilder stringBuilder = new StringBuilder();
string[] Lines = xRichTextBox.Text.Split('\n');
double d = double.Parse(xDisplacementTextBox.Text);
for(int i = 0; i < Lines.Length; ++i)
{
string newThing = double.Parse((Lines[i]) + d).ToString();
stringBuilder.AppendLine(newThing);
}
xRichTextBox.Text = stringBuilder.ToString();
This is also not letting me enter in values that have decimals (ie. 50.005)..
Look at double.Parse - as in
double x = double.Parse(xValue);
To expand, and do your work for you...
double d = double.Parse(xDisplacementTextBox.Text);
string[] Lines = xRichTextBox.Text.Split('\n');
for(int i = 0; i < Lines.Length; ++i)
{
Match lineMatch = Regex.Match(lines[i], #"^(?<p>.*)(?<x>-?\d+\.\d+)(?<y>\s+-?\d+\.\d+\s+-?\d+\.\d+)$");
if (lineMatch.Success)
{
double xValue = double.Parse(lineMatch.Groups["x"].Value) + d;
lines[i] = lineMatch.Groups["p"] + xValue + lineMatch.Groups["p"];
}
}
xRichTextBox.Text = string.Join(lines, '\n');
Too many strings and not enough data structures.
This looks like a data structure:
TEXT MORETEXT 10.505 100.994 0
TEXT MORETEXT -5.132 -12.994 90
TEXT MORETEXT 100.001 -8.994 270
So, create a class that holds
"Text" string
"MoreText" string
10.505 - double (let's call this prop1)
100.994 - double
0 - int
I'm speculating on the data values here.
Load the List<> of your class into memory.
Then, apply the text box value to your list of object every time the value changes.
PsuedoCode:
foreach(class c in List<>)
{
c.prop1 = c.prop1 + (double)Textbox.value;
}
Override ToString() in your class and display the object as needed in the rich text box.
Personally I would use a list box to display the objects.
I want to display some bold and some simple content in the form so I am using richtextbox.And I have made one file with extension of .rtf.Now I load that file in the richtextbox with use of the Loadfile() function.This works. But I want to display particular content of the file in the richtextbox,like may be first five lines or it may be line no. of six to ten.Then is there any solution ??
It is possible, just not very cleanly. This code uses another RTB to load the file and the clipboard to get the formatted RTF. Beware that it destroys the clipboard content.
using (var helper = new RichTextBox()) {
helper.LoadFile(#"c:\temp\test.rtf");
// Copy line #6
int startRange = helper.GetFirstCharIndexFromLine(5);
int endRange = helper.GetFirstCharIndexFromLine(6);
helper.SelectionStart = startRange;
helper.SelectionLength = endRange - startRange;
helper.Copy();
}
richTextBox1.SelectAll();
richTextBox1.Paste();
This doesn't preserve any formatting, but shows how you could manipulate the Lines array. It looks like the RichTextBox selfishly keeps all RTF codes to itself and only exposes text through Lines:
var fromStart = new string[richTextBox1.Lines.Length - start];
Array.Copy(richTextBox1.Lines, start, fromStart, 0, fromStart.Length);
var lineSet = fromStart.Take(count).ToArray();
richTextBox1.Lines = lineSet;
start and count are passed into this function that selects a set of lines.
Solution using ReadAllLines:
string[] lines = File.ReadAllLines(filename);
int startLine = lines.IndexOf(startMarker);
int endLine = lines.IndexOf(endMarker);
if (startLine == -1 || endLine == -1)
{
// throw some sort of exception - the markers aren't present
}
string[] section = new string[endLine - startLine - 1];
Array.Copy(lines, startLine + 1, section, 0, section.Length);
richTextBox.Rtf = string.Join("\r\n", section);
Solution using ReadAllText:
string text = File.ReadAllText(filename);
int startIndex = text.IndexOf(startMarker);
int endIndex = text.IndexOf(endMarker, startIndex + startMarker.Length);
if (startIndex == -1 || endIndex == -1)
{
// throw some sort of exception - the markers aren't present
}
richTextBox.Rtf = text.Substring(startIndex + startMarker.Length,
endIndex - startIndex - startMarker.Length);
Both of these assume that you really have got a complete RTF document in that section of the file though - you may well find you need additional header text, for example. Also, both assume the file is in UTF-8. I don't know enough about the RTF format to know if that's correct.
Did you tried the Lines property? It allows set / get string array as the RichTextbox content.