Out of Range Exception - Substring - C# - c#

I have a list of phone numbers some with extensions, some with out.
I regex my phone number to return just the digits.
I then create a string for the first 10 digits(area code + number).
I compare this strings length and compare it to the original.
If there is a difference, I use the remainder as the extension.
In the code below, I keep getting an out of range exception. I've debugged it, and it does not appear to be out of range. Anyone see what I'm missing?
var prePhone = emp.y.PhoneNumber;
if (!string.IsNullOrEmpty(prePhone))
{
string xPhone = Regex.Replace(prePhone, "[^0-9]", "");
string number = xPhone.Substring(0, 10);
int extMath = xPhone.Length - number.Length;
if (extMath >= 1)
{ int preExt = 9 + extMath;
string ext = xPhone.Substring(10, preExt);//Out of range exception
em.Phone = beautifyPhoneNumber(number, ext);
}
else {
string ext = null;
em.Phone = beautifyPhoneNumber(number, ext);
}
}

string ext = xPhone.Substring(10, preExt)
The second argument is not the ending index, it is the length of the string you want to extract.
Since preExt > 10 in your code, xPhone must be more than 20 characters in length, (since you're starting at index 10), otherwise an exception will be thrown.

Related

take only 9 chars after specific word in string [duplicate]

This question already has answers here:
Need to get a string after a "word" in a string in c#
(7 answers)
Closed 4 years ago.
I'm receiving from my app string of numbers, and I need to get them
but I don't know them
so in the string I have UID:
so search it in the string and then I need to take from the string 9 chars after the word "UID:" in the string
tried some and didn't word well
I just removing what I want and not extract it from the string
string id = txt.Substring(0, txt.LastIndexOf("UID:") + 9);
I know the string I need after UID: always have 9 chars
the out put I need to get
EXAMPLE:
UID: 994zxfa6q
I don't know what is it but I know its only have 9 chars.
I prefer not to have constants and length of constants hardcoded separate from each other. You need to have your starting index be the index of the searched string plus the size of the search string, and then your length should be the size of your id.
var uid = "UID: ";
string id = txt.Substring(txt.IndexOf(uid) + uid.Length, 9);
You definitely had the right idea. Almost had it.
string id = txt.Substring(txt.LastIndexOf("UID: ") + 5, 9);
string GetUID(string input)
{
const int uidLength = 9;
const string uidMarker = "UID: ";
var markerIndex = input.IndexOf(uidMarker);
if(markerIndex==-1 || markerIndex + uidMarker.Length + uidLength > input.Length)
{
throw new ArgumentException("Input does not contain UID", nameof(input));
}
return input.Substring(markerIndex + uidMarker.Length, uidLength);
}
If I understand what you want, you can use this code (or something along those lines). Sorry, may have gotten it wrong as I'm far from PC right now. This code assumes that there is only one "UID:" substring in the input string.
Also String.IndexOf and String.Substring are nicely documented.
Your code is almost correct, but you have to remember that the first parameter of string.SubString is an index. So, you need to change:
string id = txt.Substring(0, txt.LastIndexOf("UID:") + 9);
to:
string id = txt.Substring(txt.LastIndexOf("UID:") + 4, 9);
String txt = "UID: 994zxfa6q";
int pFrom = txt.IndexOf("UID:") + 4;
Console.WriteLine("pFrom = " + pFrom.ToString());
int pTo = txt.LastIndexOf("UID:") + 14;
Console.WriteLine("pTo= " + pTo.ToString());
String result = txt.Substring(pFrom, pTo - pFrom);
Console.WriteLine("result " + result);

Extracting substring based on the same identifier in two locations

I found this question, which achieves what I am looking for, however I only have one problem: the "start" and "end" of the substring are the same character.
My string is:
.0.label unicode "Area - 110"
and I want to extract the text between the inverted commas ("Area - 110").
In the linked question, the answers are all using specific identifiers, and IndexOf solutions. The problem is that if I do the same, IndexOf will likely return the same value.
Additionally, if I use Split methods, the text I want to keep is not a fixed length - it could be one word, it could be seven; so I am also having issues specifying the indexes of the first and last word in that collection as well.
The problem is that if I do the same, IndexOf will likely return the same value.
A common trick in this situation is to use LastIndexOf to find the location of the closing double-quote:
int start = str.IndexOf('"');
int end = str.LastIndexOf('"');
if (start >= 0 && end > start) {
// We have two separate locations
Console.WriteLine(str.Substring(start+1, end-start-1));
}
Demo.
I would to it like this:
string str = ".0.label unicode \"Area - 110\"";
str = input.SubString(input.IndexOf("\"") + 1);
str = input.SubString(0, input.IndexOf("\""));
In fact, this is one of my most used helper methods/extensions, because it is quite versatile:
/// <summary>
/// Isolates the text in between the parameters, exclusively, using invariant, case-sensitive comparison.
/// Both parameters may be null to skip either step. If specified but not found, a FormatException is thrown.
/// </summary>
public static string Isolate(this string str, string entryString, string exitString)
{
if (!string.IsNullOrEmpty(entryString))
{
int entry = str.IndexOf(entryString, StringComparison.InvariantCulture);
if (entry == -1) throw new FormatException($"String.Isolate failed: \"{entryString}\" not found in string \"{str.Truncate(80)}\".");
str = str.Substring(entry + entryString.Length);
}
if (!string.IsNullOrEmpty(exitString))
{
int exit = str.IndexOf(exitString, StringComparison.InvariantCulture);
if (exit == -1) throw new FormatException($"String.Isolate failed: \"{exitString}\" not found in string \"{str.Truncate(80)}\".");
str = str.Substring(0, exit);
}
return str;
}
You'd use that like this:
string str = ".0.label unicode \"Area - 110\"";
string output = str.Isolate("\"", "\"");

Split a filename in 2 groups

I am making an application which "Filewatches" a folder and when a file is created in there it will automatically be mailed to the customer.
The problem is that i haven't found any information on how to split filenames
For example i have a file called : "Q1040500005.xls"
I need the first 5 characters seperated from the last 5, so basically split it in half (without the extension ofcourse)
And my application has to recognize the "Q1040" and the "500005" as seperate strings.
Which will be recognized in the database which contains The query number (Q1040) and the customer number "500005" the email of the customer and the subject of the queryfile.
How can i do this the easiest way?
Thanks for the help!
Use SubString method http://msdn.microsoft.com/es-es/library/aka44szs(v=vs.80).aspx
int lengthFilename = filename.Length - 4; //substract the string ".xls";
int middleLength = lengthFilename/2;
String filenameA = filename.SubString(0, middleLength);
String filenameB = filename.SubString(middleLength, lengthFilename - middleLength);
Is string.Substring method what you're looking for?
Use String.SubString(int startindex, int length)
String filename = Q1040500005.xls
var queryNumber = filename.Substring(0, 5); //Q1040
var customerNumber = filename.Substring(5, 6); //500005
This assumes your strings are a constant length.
Hope this helps.
You can use string.SubString() here
string a = fileName.SubString(0, 5); // "Q1040"
string b = fileName.SubString(5, 5); // "50000" <- Are you sure you didn't mean "last 6"?
string b2 = fileName.SubString(5, 6); // "500005"
This only works, if both strings have a constant fixed length
Edit:
If on the other hand, both strings can have variable length, I'd recommend you use a separator to divide them ("Q1040-500005.xml"), then use string.Split()
string[] separatedStrings = fileName.Split(new char[] { '-', '.' });
string a = separated[0]; // "Q1040"
string b = separated[1]; // "500005"
string extension = separated[2]; // "xls"

Substring index and length must refer to a location within the string

I have a string that looks like
string url = "www.example.com/aaa/bbb.jpg";
"www.example.com/" is 18 fixed in length. I want to get the "aaa/bbb" part from this string (The actual url is not example nor aaa/bbb though, the length may vary)
so here's what I did:
string newString = url.Substring(18, url.Length - 4);
Then I got the exception: index and length must refer to a location within the string. What's wrong with my code and how to fix it?
The second parameter in Substring is the length of the substring, not the end index (in other words, it's not the length of the full string).
You should probably include handling to check that it does indeed start with what you expect, end with what you expect, and is at least as long as you expect. And then if it doesn't match, you can either do something else or throw a meaningful error.
Here's some example code that validates that url contains your strings, that also is refactored a bit to make it easier to change the prefix/suffix to strip:
var prefix = "www.example.com/";
var suffix = ".jpg";
string url = "www.example.com/aaa/bbb.jpg";
if (url.StartsWith(prefix) && url.EndsWith(suffix) && url.Length >= (prefix.Length + suffix.Length))
{
string newString = url.Substring(prefix.Length, url.Length - prefix.Length - suffix.Length);
Console.WriteLine(newString);
}
else
//handle invalid state
Your mistake is the parameters to Substring. The first parameter should be the start index and the second should be the length or offset from the startindex.
string newString = url.Substring(18, 7);
If the length of the substring can vary you need to calculate the length.
Something in the direction of (url.Length - 18) - 4 (or url.Length - 22)
In the end it will look something like this
string newString = url.Substring(18, url.Length - 22);
How about something like this :
string url = "http://www.example.com/aaa/bbb.jpg";
Uri uri = new Uri(url);
string path_Query = uri.PathAndQuery;
string extension = Path.GetExtension(path_Query);
path_Query = path_Query.Replace(extension, string.Empty);// This will remove extension
You need to find the position of the first /, and then calculate the portion you want:
string url = "www.example.com/aaa/bbb.jpg";
int Idx = url.IndexOf("/");
string yourValue = url.Substring(Idx + 1, url.Length - Idx - 4);
Try This:
int positionOfJPG=url.IndexOf(".jpg");
string newString = url.Substring(18, url.Length - positionOfJPG);
string newString = url.Substring(18, (url.LastIndexOf(".") - 18))
Here is another suggestion. If you can prepend http:// to your url string you can do this
string path = "http://www.example.com/aaa/bbb.jpg";
Uri uri = new Uri(path);
string expectedString =
uri.PathAndQuery.Remove(uri.PathAndQuery.LastIndexOf("."));
You need to check your statement like this :
string url = "www.example.com/aaa/bbb.jpg";
string lenght = url.Lenght-4;
if(url.Lenght > 15)//eg 15
{
string newString = url.Substring(18, lenght);
}
Can you try this ?
string example = url.Substring(0,(url.Length > 18 ? url.Length - 4 : url.Length))

How to extract string at a certain character that is repeated within string?

How can I get "MyLibrary.Resources.Images.Properties" and "Condo.gif" from a "MyLibrary.Resources.Images.Properties.Condo.gif" string.
I also need it to be able to handle something like "MyLibrary.Resources.Images.Properties.legend.House.gif" and return "House.gif" and "MyLibrary.Resources.Images.Properties.legend".
IndexOf LastIndexOf wouldn't work because I need the second to last '.' character.
Thanks in advance!
UPDATE
Thanks for the answers so far but I really need it to be able to handle different namespaces. So really what I'm asking is how to I split on the second to last character in a string?
You can use LINQ to do something like this:
string target = "MyLibrary.Resources.Images.Properties.legend.House.gif";
var elements = target.Split('.');
const int NumberOfFileNameElements = 2;
string fileName = string.Join(
".",
elements.Skip(elements.Length - NumberOfFileNameElements));
string path = string.Join(
".",
elements.Take(elements.Length - NumberOfFileNameElements));
This assumes that the file name part only contains a single . character, so to get it you skip the number of remaining elements.
You can either use a Regex or String.Split with '.' as the separator and return the second-to-last + '.' + last pieces.
You can look for IndexOf("MyLibrary.Resources.Images.Properties."), add that to MyLibrary.Resources.Images.Properties.".Length and then .Substring(..) from that position
If you know exactly what you're looking for, and it's trailing, you could use string.endswith. Something like
if("MyLibrary.Resources.Images.Properties.Condo.gif".EndsWith("Condo.gif"))
If that's not the case check out regular expressions. Then you could do something like
if(Regex.IsMatch("Condo.gif"))
Or a more generic way: split the string on '.' then grab the last two items in the array.
string input = "MyLibrary.Resources.Images.Properties.legend.House.gif";
//if string isn't already validated, make sure there are at least two
//periods here or you'll error out later on.
int index = input.LastIndexOf('.', input.LastIndexOf('.') - 1);
string first = input.Substring(0, index);
string second = input.Substring(index + 1);
Try splitting the string into an array, by separating it by each '.' character.
You will then have something like:
{"MyLibrary", "Resources", "Images", "Properties", "legend", "House", "gif"}
You can then take the last two elements.
Just break down and do it in a char loop:
int NthLastIndexOf(string str, char ch, int n)
{
if (n <= 0) throw new ArgumentException();
for (int idx = str.Length - 1; idx >= 0; --idx)
if (str[idx] == ch && --n == 0)
return idx;
return -1;
}
This is less expensive than trying to coax it using string splitting methods and isn't a whole lot of code.
string s = "1.2.3.4.5";
int idx = NthLastIndexOf(s, '.', 3);
string a = s.Substring(0, idx); // "1.2"
string b = s.Substring(idx + 1); // "3.4.5"

Categories