I have a text string that when it exceeds a specific length, I separate the string into 2 strings, passing the rest of the remaining content to another variable, but I have an exception
Index and length must refer to a location within the string. (Parameter 'length')
My C# code:
string text = "Hello word jeje";
if (text.Length > 10)
{
string stringOne = text.Substring(0, 10);
string stringTwo = text.Substring(11, text.Length); //throw exception
}
expected result:
string text = "Hello word jeje";
string stringOne = "Hello";
string stringTwo = " jeje";
You have an off-by-one error; you'd need text.Length - 1.
The two-argument version of String.Substring() accepts start and length arguments; you'd need text.Substring(11, text.Length - 11).
However, you can just leave the second argument off for the second half, since the single-argument version of String.Substring() returns a substring to the end of the string.
string stringOne = text.Substring(0, 10);
string stringTwo = text.Substring(11);
How about using the Linq Chunk() extension method?
var test = "Hello World Yeah";
var chunks = test.Chunk(10);
foreach (var chunk in chunks)
{
var subtext = new string(chunk.ToArray());
Console.WriteLine(subtext);
}
Output:
Hello Worl
d Yeah
Related
Here is an example of what I want to implement: for instance, given the string Something, if you were to replace all occurrences of so with DDD, the result would be DDDmething.
Here is how I am implementing it; my code finds a char by its specific position and changes it, but in fact I want to implement what I stated above.
static void Main(string[] args)
{
string str = "The Haunting of Hill House!";
Console.WriteLine("String: " + str);
// replacing character at position 7
int pos = 7;
char rep = 'p';
string res = str.Substring(0, pos) + rep + str.Substring(pos + 1);
Console.WriteLine("String after replacing a character: " + result);
Console.ReadLine();
}
Alternative might be to split the string by "so" and join the resulting array by "DDD" :
string result = string.Join("DDD", "something".Split(new[] { "so" }, StringSplitOptions.None));
This should do what you want. The idea is to use IndexOf to find the index of the substring to replace then append the substring before it followed by the replacement, then start the search over from the end of the found substring. Then after all substrings are found and replaced append the rest of the original string to the end if there is any.
Note this doesn't do any checks on the input and you really should use the string.Replace as I'm sure it's more performant.
public string Replace(string input, string find, string replace)
{
// The current index in the string where we are searching from
int currIndex = 0;
// The index of the next substring to replace
int index = input.IndexOf(find);
// A string builder used to build the new string
var builder = new StringBuilder();
// Continue until the substring is not found
while(index != -1)
{
// If the current index is not equal to the substring location
// when we need to append everything from the current position
// to where we found the substring
if(index != currIndex )
{
builder.Append(input.Substring(currIndex , index - currIndex));
}
// Now append the replacement
builder.Append(replace);
// Move the current position past the found substring
currIndex = index + find.Length;
// Search for the next substring.
index = input.IndexOf(find, currIndex );
}
// If the current position is not the end of the string we need
// to append the remainder of the string.
if(currIndex < input.Length)
{
builder.Append(input.Substring(currIndex));
}
return builder.ToString();
}
You could do it like this:
var someString = "This is some sort of string.";
var resultIndex = 0;
var searchKey ="So";
var replacementString = "DDD";
while ((resultIndex = someString.IndexOf(searchKey, resultIndex, StringComparison.OrdinalIgnoreCase)) != -1)
{
var prefix = someString.Substring(0, Math.Max(0, resultIndex - 1));
var suffix = someString.Substring(resultIndex + searchKey.Length);
someString = prefix + replacementString + suffix;
resultIndex += searchKey.Length;
}
Expected to produce "This is DDDme DDDrt of string.".
I'm using C#, and have the following string text value:
get directions from Sydney to Melbourne
And this is the code that I have at the moment to try and get the text that appears between From and To
String fromDestination = InputTextbox.Text;
if (fromDestination.Contains("from"))
{
fromDestination = fromDestination.Substring(fromDestination.IndexOf("from") + 5, fromDestination.IndexOf("to") - 3);
}
That code removes the word "from" from the returned value, but I cannot work out how to get ride of the "to". The output at the moment is:
sydney to Melb
Thanks for any help.
Here's another possible route (lolpun)..
You can split via "from" and "to". Each part is created for you then:
var str = "get directions from Sydney to Melbourne";
var parts = str.Split(new string[] { "from", "to" }, StringSplitOptions.None); // split it up
var from = parts[1]; // index 1 is from
var to = parts[2]; // index 2 is to
Console.WriteLine(from); // "Sydney"
Console.WriteLine(to); // "Melbourne"
The second parameter to pass to the Substring method is the number of chars to extract from the instance string, not another position
String fromDestination = InputTextbox.Text;
int pos = fromDestination.IndexOf(" from ");
if(pos >= 0)
{
int pos2 = fromDestination.IndexOf(" to ", pos);
if(pos2 > -1)
{
int len = pos2 - (pos + 6);
fromDestination = fromDestination.Substring(pos+6, len);
}
}
Notice that I have changed the search strings adding a space before and after from and to. This is a precautional measure required to avoid false positives when a city name contains 'to' as part of its name or if there is another from embedded in the text before the actual starting from
If the string is always the same I would suggest a simple string split.
string fromDestination = InputTextbox.Text.Split(' ')[3];
You can also use regular expressions:
String fromDestination = "get directions from Sydney to Melbourne";
var match = Regex.Match(fromDestination, #"(?<=from\s).*(?=\sto)");
if (match.Groups.Count > 0)
fromDestination = match.Groups[0].Value;
Substring(startIndex, length)
for compute the length you should try to fromDestination.Length - fromDestination.IndexOf(" to ")
fromDestination.Substring(fromDestination.IndexOf(" from ") + 5, fromDestination.Length - fromDestination.IndexOf(" to "));
This will get you the string "Sydney Melbourne":
string fromDestination = "get directions from Sydney to Melbourne";
string result = fromDestination.Substring(fromDestination.IndexOf("from") + 5).Replace("to", "");
By the look you probably would be better off replacing the textbox for 2 comboboxes,each with their items filled by a predefined list of available cities so the user cannot enter any typos for example and you just react to the selectedindex of the combobox...
How can I overwrite a string ? Example:
string text = "abcdefghijklmnopqrstuvwxyz".OverwriteWith("hello world", 3);
// text == "abchello worldopqrstuvwxyz"
Of course this method doesn't exist. But
Is there something build in in .NET Framework ?
If not, how can I efficiently write a string into another string ?
Short answer, you cannot. Strings are an immutable type. This means that once they are created, they cannot be modified.
If you want to manipulated strings in memory, the c++ way, you should use a StringBuilder.
You just need to use String.Remove and String.Insert method like;
string text = "abcdefghijklmnopqrstuvwxyz";
if(text.Length > "hello world".Length + 3)
{
text = text.Remove(3, "hello world".Length).Insert(3, "hello world");
Console.WriteLine(text);
}
Output will be;
abchello worldopqrstuvwxyz
Here a DEMO.
Remember, strings are immutable types in .NET. You can't change them. Even if you think you change them, you actually create a new string objects.
If you want to work with mutable strings, take a look at StringBuilder class.
This class represents a string-like object whose value is a mutable
sequence of characters. The value is said to be mutable because it can
be modified once it has been created by appending, removing,
replacing, or inserting characters.
You can Try this Solution this may help you..
var theString = "ABCDEFGHIJ";
var aStringBuilder = new StringBuilder(theString);
aStringBuilder.Remove(3, 2); //Used to Remove the
aStringBuilder.Replace(); //Write the Required Function in the Replace
theString = aStringBuilder.ToString();
Reference : Click Here!!
What you want is an extension method:
static class StringEx
{
public static string OverwriteWith(this string str, string value, int index)
{
if (index + value.Length < str.Length)
{
// Replace substring
return str.Remove(index) + value + str.Substring(index + value.Length);
}
else if (str.Length == index)
{
// Append
return str + value;
}
else
{
// Remove ending part + append
return str.Remove(index) + value;
}
}
}
// abchello worldopqrstuvwxyz
string text = "abcdefghijklmnopqrstuvwxyz".OverwriteWith("hello world", 3);
// abchello world
string text2 = "abcd".OverwriteWith("hello world", 3);
// abchello world
string text3 = "abc".OverwriteWith("hello world", 3);
// hello world
string text4 = "abc".OverwriteWith("hello world", 0);
I want to create a method that reads from every line from a file. Next, it has to check between the pipes and determine if there are words that are more than three characters long, and are only numbers. In the file are strings organized like this:
What's going on {noway|that's cool|1293328|why|don't know|see}
With this sentence, the software should remove 1293328.
The resulting sentence would be:
What's going on {noway|that's cool|don't know}
Until now I am reading every line from the file and I made the functions that determine if the words between | | have to be deleted or not (checking a string like noway,that's cool, etc)
I don't know how to get the strings between the pipes.
You can split a string by a character using the Split method.
string YourStringVariable = "{noway|that's cool|1293328|why|don't know|see}";
YourStringVariable.Split('|'); //Returns an array of the strings between the brackets
What's about:
string RemoveValues(string sentence, string[] values){
foreach(string s in values){
while(sentence.IndexOf("|" + s) != -1 && sentence.IndexOf("|" + s) != 0){
sentence = sentence.Remove(sentence.IndexOf("|" + s), s.Lenght + 1);
}
}
return sentence;
}
In your case:
string[] values = new string[3]{ "1293328", "why", "see" };
string sentence = RemoveValues("noway|that's cool|1293328|why|don't know|see", values);
//result: noway|that's cool|don't know
string YourStringVariable = "{noway|that's cool|1293328|why|don't know|see}";
string[] SplitValue=g.Split('|');
string FinalValue = string.Empty;
for (int i = 0; i < SplitValue.Length; i++)
{
if (!SplitValue[i].ToString().Any(char.IsDigit))
{
FinalValue += SplitValue[i]+"|";
}
}
I have a string like this: C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg
Now, what I want to do is to dynamically combine the last 4 numbers, in this case its 10000080 as result. My idea was ti split this and combine them in some way, is there an easier way? I cant rely on the array index, because the path can be longer or shorter as well.
Is there a nice way to do that?
Thanks :)
A compact way using string.Join and Regex.Split.
string text = #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
string newString = string.Join(null, Regex.Split(text, #"[^\d]")); //10000080
Use String.Split
String toSplit = "C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
String[] parts = toSplit.Split(new String[] { #"\" });
String result = String.Empty;
for (int i = 5, i > 1; i--)
{
result += parts[parts.Length - i];
}
// Gives the result 10000080
You can rely on array index if the last part always is the filename.
since the last part is always
array_name[array_name.length - 1]
the 4 parts before that can be found by
array_name[array_name.length - 2]
array_name[array_name.length - 3]
etc
If you always want to combine the last four numbers, split the string (use \ as the separator), start counting from the last part and take 4 numbers, or the 4 almost last parts.
If you want to take all the digits, just scan the string from start to finish and copy just the digits to a new string.
string input = "C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
string[] parts = toSplit.Split(new char[] {'\\'});
IEnumerable<string> reversed = parts.Reverse();
IEnumerable<string> selected = reversed.Skip(1).Take(4).Reverse();
string result = string.Concat(selected);
The idea is to extract the parts, reverse them to keep only the last 4 (excluding the file name) and re reversing to rollback to the initial order, then concat.
Using LINQ:
string path = #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg";
var parts = Path.GetDirectoryName(path).Split('\\');
string numbersPart = parts.Skip(parts.Count() - 4)
.Aggregate((acc, next) => acc + next);
Result: "10000080"
var r = new Regex(#"[^\d+]");
var match = r
.Split(#"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg")
.Aggregate((i, j) => i + j);
return match.ToString();
to find the number you can use regex:
(([0-9]{2})\\){4}
use concat all inner Group ([0-9]{2}) to get your searched number.
This will always find your searched number in any position in the given string.
Sample Code:
static class TestClass {
static void Main(string[] args) {
string[] tests = { #"C:\Projects\test\whatever\files\media\10\00\00\80\test.jpg",
#"C:\Projects\test\whatever\files\media\10\00\00\80\some\foldertest.jpg",
#"C:\10\00\00\80\test.jpg",
#"C:\10\00\00\80\test.jpg"};
foreach (string test in tests) {
int number = ExtractNumber(test);
Console.WriteLine(number);
}
Console.ReadLine();
}
static int ExtractNumber(string path) {
Match match = Regex.Match(path, #"(([0-9]{2})\\){4}");
if (!match.Success) {
throw new Exception("The string does not contain the defined Number");
}
//get second group that is where the number is
Group #group = match.Groups[2];
//now concat all captures
StringBuilder builder = new StringBuilder();
foreach (var capture in #group.Captures) {
builder.Append(capture);
}
//pares it as string and off we go!
return int.Parse(builder.ToString());
}
}