I've got a RichTextBox, and would like to highlight a whole word, given just its starting index.
I've been able to highlight a word if the starting index and length is known, however in this case I do not know the length of the word. Is it possible to highlight from a starting index to the first occurance of a space?
UPDATE:
This is what I've tried so far:
resultsRichTextBox.Select(novelOffset - 2, searchString.Length);
Unfortunately 'searchstring' is not always the length of the word being searched for, so I need a way of finding the amount of characters from novelOffset - 2 till the nearest space.
You can do something like this:
int length = this.richTextBox1.Text.Skip(startIdx)
.TakeWhile(x => char.IsLetterOrDigit(x))
.Count();
this.richTextBox1.Select(startIdx, length);
this.richTextBox1.SelectionBackColor = Color.Yellow;
Obviously you can change char.IsLetterOrDigit with x != ' ' or whatever you prefer.
You can use the String.IndexOf(Char, Int32):
Reports the zero-based index of the first occurrence of the specified
Unicode character in this string. The search starts at a specified
character position.
It will give you the starting and end index of your word. You can then highlight it!
int endIndex = resultsRichTextBox.Text.IndexOf(' ', novelOffset - 2);
resultsRichTextBox.Select(novelOffset - 2, (endIndex - (novelOffset - 2)) );
You only need to handle what happens if it doesn't find any space after the word. The endIndex value will be -1 if that happens. I would simply set the value of endIndex to searchString.Length.
int startIndex;
//fill startIndex with the known value
int endIndex = startIndex;
while(rtb.Text.CharAt(endIndex) != ' ' && endIndex < rtb.Text.Length)
{
endIndex++;
}
rtb.Select(startIndex, endIndex);
You can use a Find method given you provide the starting index of the word and look for the SPACE. Find will return you the index of next space and in fact the end of the word (found - 1).
You can then use a select call.
Related
I know it may not be a best-practice solution for my problem but I'd tried to remove the first and last specific characters of a string.
Here's a string for example: "product"". I'd like to remove only the first and last " characters so the expected result would be: product".
Here's my code that produced some unexpected results and I'd like to understand why it is working like that.
var productName = "\"product\"\""; // "product""
productName.IndexOf('\"', 0) and productName.LastIndexOf('\"', 0) would be both 0 here at this point.
if (productName.IndexOf('\"', 0) == 0) productName = productName.Remove(productName.IndexOf('\"', 0), 1);
In this condition, IndexOf returns 0 as expected so productName's value will be productName"" at this point. Then, I run the following:
if (productName.LastIndexOf('\"', 0) == 0) productName = productName.Remove(productName.LastIndexOf('\"', 0), 1);
In this condition, LastIndexOf returns -1. It acts as if my variable's length remains the same after Remove but its value is shifted to the left by 1 character. Why is that?
Let's take a look at the docs for string.LastIndexOf(char, int):
Reports the zero-based index position of the last occurrence of a specified string within this instance. The search starts at a specified character position and proceeds backward toward the beginning of the string.
...
startIndex
Int32
The search starting position. The search proceeds from startIndex toward the beginning of this instance.
You're calling:
productName.LastIndexOf('\"', 0)
So you're starting at the first character in your string (index 0), and proceeding towards the beginning looking for a " character. But you're already at the beginning! So you're not going to find anything.
Just use the overloads which don't take a startIndex: you don't need it:
string.IndexOf('"')
string.LastIndexOf('"')
Please try this
var productName = "\"product\"\"";
if (productName.IndexOf('\"', 0) == 0)
productName = productName.Remove(productName.IndexOf('\"', 0), 1);
if (productName.LastIndexOf('\"', productName.Length-1) == productName.Length - 1)
productName = productName.Remove(productName.LastIndexOf('\"', productName.Length - 1), 1);
I have a string which contains a lot of useless information after the first char: space. So I built a StringBuilder to remove unnecesary characters after the first space.
public static string Remove(string text)
{
int index1 = text.IndexOf(' ');
int index2 = text.Lenght;
StringBuilder sv = new StringBuilder(text.Lenght);
sv.Append(text);
sv.Remove(index1, index2);
string text2 = sv.ToString();
return text2;
}
Can somebody explain why this throws me an error? Thank you!
The reason for this exception is that you misunderstood the purpose of the second parameter: rather than specifying the ending index, it specifies the length of the segment to be removed.
Since your code is passing the length of the entire text string, the only valid input for the first parameter would be zero. To pass a proper value, subtract the first index from the second index, and add 1 to the result.
Note: It looks like you are removing everything from the string starting at the first space ' '. A simpler way of doing it would be with substring:
int index = text.IndexOf(' ');
return index >= 0 ? text.Substring(0, index) : text;
The documentation for Remove says it all - only one exception is raised for that method
ArgumentOutOfRangeException: If startIndex or length is less than zero, or startIndex + length is greater than the length of this instance.
So one of two things is going on
Your string does not contain a space (startIndex will be less than zero)
The startIndex+length is greater than the total length of the string.
Crucially, with the code you've posted 1. above could sometimes be true, and 2. will always be true! You should have done index2-index1 for the second parameter.
Let's say I have a string called test,
string test = "hello my dear world"
and I want to get the last letter's index, (which is 19) .
How do I get that index, and insert it into an int/string?
This is extremely simple.
string test = "Hello World";
char theLastCharacterOfTest = test[test.Length - 1]; // 'd'
int theIndexOfTheLastCharacter = test.Length - 1; // 10
Want an explanation? Here it is!
Let's start with getting the index of the last character. Since C# uses a 0-based index system (i.e. the first index is 0), the last index is the length of the string - 1.
The last character is just the character at the last index, right? And the indexer of string returns the character at the index passed in. If we combine these two, we get test[test.Length - 1].
I don't think you are very familiar with indexers, so here's a link:
https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx
I'm not sure whether you're looking for the index or position of the last character (you said the index is 19, but that's the position...the index is 18). Here's both:
string test = "hello my dear world";
// The length of the text gives the position of the last char
int position = test.Length;
// C# has a 0-based index. You need the string length -1 to get the last char's position
int index = test.Length - 1;
Here's a working example.
int index = test.Length;
char LastLetter = test[index - 1];
please search , before posting your question.
string test = "hello my dear world";
int index = test.FindIndex(x => x.StartsWith("d"));
OR
int index = test.Length - 1;
I've got a RichTextBox, and would like to highlight a whole word, given just its ending index. Is it possible to highlight from an ending index, backwards to the first occurance of a space?
This is what I've tried so far, but I don't know if there is any other efficient methods:
int length = richTextBox.Text.Reverse().Skip(richTextBox.Text.Length - offset)
.TakeWhile(x => x != ' ')
.Count();
richTextBox.Select(offset - length, length + 1);
richTextBox.SelectionBackColor = Color.Yellow;
That's a very inefficient way to get the length.
Try this- might be off by one somewhere, I cant test it right now:
var prevSpace = richTextBox.Text.LastIndexOf(' ', offset);
var length = prevSpace = -1 ? offset + 1 : offset - prevspace;
I am trying to solve the following problem but cannot find an elegant solution. Any ideas?
Thanks.
Input - a variable length string of numbers, e.g.,
string str = "5557476374202110373551116201";
Task - Check (from left to right) that each number (ignoring the repetitions) does not appear in the following 2 indexes. Using eg. above, First number = 5. Ignoring reps we see that last index of 5 in the group is 2. So we check next 2 indexes, i.e. 3 and 4 should not have 5. If it does we count it as error. Goal is to count such errors in the string.
In the above string errors are at indexes, 3,10 and 16.
in addition to the other excellent solutions you can use a simple regexp:
foreach (Match m in Regexp.Matches(str, #"(\d)(?!\1)(?=\d\1)"))
Console.WriteLine("Error: " + m.Index);
returns 3,10,16. this would match adjacent errors using lookahead with a backreference. handles repetitions. .net should support that. if not, you can use a non-backreference version:
(?<=0[^0])0|(?<=1[^1])1|(?<=2[^2])2|(?<=3[^3])3|(?<=4[^4])4|(?<=5[^5])5|(?<=6[^6])6|(?<=7[^7])7|(?<=8[^8])8|(?<=9[^9])9
A simple indexed for loop with a couple of look ahead if checks would work. You can treat a string as a char[] or as an IEnumerable - either way you can use that to loop over all of the characters and perform a lookahead check to see if the following one or two characters is a duplicate.
Sorry, not a C# man, but here's a simple solution in Ruby:
a="5557476374202110373551116201"
0.upto(a.length) do |i|
puts "error at #{i}" if a[i]!=a[i+1] && a[i]==a[i+2]
end
Output:
error at 3
error at 10
error at 16
Here's something I threw together in C# that worked with the example input from the question. I haven't checked it that thoroughly, though...
public static IEnumerable<int> GetErrorIndices(string text) {
if (string.IsNullOrEmpty(text))
yield break;
int i = 0;
while (i < text.Length) {
char c = text[i];
// get the index of the next character that isn't a repetition
int nextIndex = i + 1;
while (nextIndex < text.Length && text[nextIndex] == c)
nextIndex++;
// if we've reached the end of the string, there's no error
if (nextIndex + 1 >= text.Length)
break;
// we actually only care about text[nextIndex + 1],
// NOT text[nextIndex] ... why? because text[nextIndex]
// CAN'T be a repetition (we already skipped to the first
// non-repetition)
if (text[nextIndex + 1] == c)
yield return i;
i = nextIndex;
}
yield break;
}