I want to search for a given string, within another string (Ex. find if "something" exists inside "something like this". How can I do the following? :
Know the position in which "something" is located (in the curr. ex. this is = 0.
Extract everything to the left or to the right, up to the char. found (see 1).
Extract a substring beggining where the sought string was found, all the way to X amount of chars (in Visual Basic 6/VBA I would use the Mid function).
string searched = "something like this";
1.
int pos = searched.IndexOf("something");
2.
string start = searched.Substring(0, pos);
string endstring = searched.Substring(pos);
3.
string mid = searched.Substring(pos, x);
Have you looked at the String.SubString() method? You can use the IndexOf() method to see if the substring exists first.
Take a look at the System.String member functions, in particular the IndexOf method.
Use int String.IndexOf(String).
I would do something like this:
string s = "I have something like this";
//question No. 1
int pos = s.IndexOf("something");
//quiestion No. 2
string[] separator = {"something"};
string[] leftAndRightEntries = s.Split(separator, StringSplitOptions.None);
//question No. 3
int x = pos + 10;
string substring = s.Substring(pos, x);
I would avoid using Split, as it's designed to give you multiple results. I would stick with the code in the first example, though the second block should actually read...
string start = searched.Substring(0, pos);
string endstring;
if(pos < searched.Length - 1)
endstring = searched.Substring(pos + "something".Length);
else
endstring = string.Empty
The key difference is accounting for the length of the string to find (hence the rather odd-looking "something".Length, as this example is designed for you to be able to plop in your own variable).
Related
I want to split a string only at last occurrence of special character.
I try to parse a name of a tab from browser, so my initial string looks for example like this:
Untitled - Google Chrome
That is easy to solve as there is a Split function. Here is my implementation:
var pageparts= Regex.Split(inputWindow.ToString(), " - ");
InsertWindowName(pageparts[0].ToString(), pageparts[1].ToString());//method to save string into separate columns in DB
This works, but problem occurs, when I get a page like this:
SQL injection - Wikipedia, the free encyclopedia - Mozilla Firefox
Here are two dashes, which means, that after split is done, there are 3 separate strings in array and if I would continue normally, database would contain in first column value "SQL injection" and in second column value "Wikipedia, the free encyclopedia". Last value will be completely left out.
What I want is that first column in database will have value:
SQL injection - Wikipedia, the free encyclopedia" and second column will have:
"Mozilla Firefox". Is that somehow possible?
I tried to use a Split(" - ").Last() function (even LastOrDefault() too), but then I only got a last string. I need to get both side of the original string. Just separated by last dash.
You can use String.Substring with String.LastIndexOf:
string str = "SQL injection - Wikipedia, the free encyclopedia - Mozilla Firefox";
int lastIndex = str.LastIndexOf('-');
if (lastIndex + 1 < str.Length)
{
string firstPart = str.Substring(0, lastIndex);
string secondPart = str.Substring(lastIndex + 1);
}
Create a extension method (or a simple method) to perform that operation and also add some error checking for lastIndex.
EDIT:
If you want to split on " - " (space-space) then use following to calculate lastIndex
string str = "FirstPart - Mozzila Firefox-somethingWithoutSpace";
string delimiter = " - ";
int lastIndex = str.LastIndexOf(delimiter);
if (lastIndex + delimiter.Length < str.Length)
{
string firstPart = str.Substring(0, lastIndex);
string secondPart = str.Substring(lastIndex + delimiter.Length);
}
So for string like:
"FirstPart - Mozzila Firefox-somethingWithoutSpace"
Output would be:
FirstPart
Mozzila Firefox-somethingWithoutSpace
Please forgive me for my laziness ins this solution i'm sure there is a better approach but i will give you one solution proposal i'm assuming you are codding in C#.
First of all correct me if I get wrongly the question no matter what you just want to columns returned the first (all text even of it includes dashes but the last one) and last column (all the text after last dash) if it's ok. let's do it.
// I Only use split function when I want all data in separate variable (array position) in you case I assumed that you just want 2 values (if possible), so you can use substring.
static void Main(string[] args)
{
string firstname = "";
string lastName = "";
string variablewithdata = "SQL injection - Wikipedia, -the free encyclopedia - Mozilla Firefox";
// variablewithdata.LastIndexOf('-') = returns Integer corresponding to the last position of that character.
//I suggest you validate if variablewithdata.LastIndexOf('-') is equal to -1 or not because if it don't found your character it returns -1 so if the value isn't -1 you can substring
firstname = variablewithdata.Substring(0, (variablewithdata.LastIndexOf('-') - 1));
lastName = variablewithdata.Substring(variablewithdata.LastIndexOf('-') + 1);
Console.WriteLine("FirstColumn: {0} \nLastColumn:{1}",firstname,lastName);
Console.ReadLine();
}
If it's not what you want can you explain me for example for "SQL injection - Wikipedia,- the free - encyclopedia - Mozilla Firefox" what's suppose to be returned?
Forgive me for unclean code i'm bored today.
If you don't care about reassembling strings, you could use something like :
var pageparts= Regex.Split(inputWindow.ToString(), " - ");
var firstPart = string.Join(" - ", pageparts.Take(pageparts.Length - 1));
var secondPart = pageparts.Last()
InsertWindowName(firstPart, secondPart);
I have a file called file_test1.txt and I want to extract just test1 from the name and place it in a string. Whats the best way of doing this?
E.g.
string fullfile = #"C:\file_test1.txt";
string section = [test1] from fullfile; // <- expected result
I want to be able to split on 'file_' and '.txt' as the 'test1' section could be larger or smaller however the 'file_' and '.txt' will always be the same.
Try Path.GetFileNameWithoutExtension(fullfile).Substring(5) (or Substring("TEMPLATE_PREFIX".Length))
You can try spilt
var test = Path.GetFileNameWithoutExtension(fullfile).split('_')[1];
Try following
string fullfile = #"C:\file_test1.txt";
var name = fullfile.Substring(8,fullfile.Length-12)
As c:\file_ and .txt are fixed, You can take Substring starting at index 8 (skip leading name), upto length of total string length - 12 (12 => length of leading name, and trailing extension)
Thought I'd give a solution that uses Split and handles files with multiple underscores:
string.Join("_", Path.GetFileNameWithoutExtension(file).Split('_').Skip(1));
String.Split() works quite well for my uses:
http://msdn.microsoft.com/en-us/library/b873y76a.aspx
Obviously many ways to accomplish this. Here's yet another approach:
string fullfile = #"C:\file_test1.txt";
int index1 = fullfile.LastIndexOf("file_");
if (index1 != -1)
{
int index2 = fullfile.IndexOf(".", index1);
if (index2 != -1)
{
string section = fullfile.Substring(index1 + 5, index2 - index1 - 5);
}
}
You could also get "test1", or any subsequent filename (assuming your file naming convention remains constant!) using this regular expression:
var defaultRegex = new Regex(#"(?<=_).*(?=.txt)");
var matches = defaultRegex.Matches(fullfile);
var match = matches[0].Value;
The regular expression:
(?<=_).*(?=.txt)
uses positive look behind to find text preceded by '_', and also positive lookahead to find text which has '.txt' ahead of it.
I have the following:
string test = "9586-202-10072"
How would I get all characters to the right of the final - so 10072. The number of characters is always different to the right of the last dash.
How can this be done?
You can get the position of the last - with str.LastIndexOf('-'). So the next step is obvious:
var result = str.Substring(str.LastIndexOf('-') + 1);
Correction:
As Brian states below, using this on a string with no dashes will result in the original string being returned.
You could use LINQ, and save yourself the explicit parsing:
string test = "9586-202-10072";
string lastFragment = test.Split('-').Last();
Console.WriteLine(lastFragment);
I can see this post was viewed over 46,000 times. I would bet many of the 46,000 viewers are asking this question simply because they just want the file name... and these answers can be a rabbit hole if you cannot make your substring verbatim using the at sign.
If you simply want to get the file name, then there is a simple answer which should be mentioned here. Even if it's not the precise answer to the question.
result = Path.GetFileName(fileName);
see https://msdn.microsoft.com/en-us/library/system.io.path.getfilename(v=vs.110).aspx
string tail = test.Substring(test.LastIndexOf('-') + 1);
YourString.Substring(YourString.LastIndexOf("-"));
With the latest C# 8 and later you can use Range Indexer as follows:-
string test = "9586-202-10072"
var foo = test?[(test.LastIndexOf('-') + 1)..];
// foo is => 10072
string atest = "9586-202-10072";
int indexOfHyphen = atest.LastIndexOf("-");
if (indexOfHyphen >= 0)
{
string contentAfterLastHyphen = atest.Substring(indexOfHyphen + 1);
Console.WriteLine(contentAfterLastHyphen );
}
See String.lastIndexOf method
I created a string extension for this, hope it helps.
public static string GetStringAfterChar(this string value, char substring)
{
if (!string.IsNullOrWhiteSpace(value))
{
var index = value.LastIndexOf(substring);
return index > 0 ? value.Substring(index + 1) : value;
}
return string.Empty;
}
test.Substring[(test.LastIndexOf('-') + 1)..]
C# 8 (late 2019) introduces range operator and simplifies it a bit further. The two dots here means from the index (inclusive) till the end of string.
test.Substring(test.LastIndexOf("-"))
and... in case you need the left part of a string:
private string AllTheLeftPart(string theString)
{
string rightPart = theString.Substring(theString.LastIndexOf('-') + 1);
string leftPart theString.Replace("-" + rightPart, String.Empty);
return leftPart ;
}
I have a string "8329874566".
I want to place - in the string like this "832-98-4566"
Which string function can I use?
I would have done something like this..
string value = "8329874566";
value = value.Insert(6, "-").Insert(3, "-");
You convert it to a number and then format the string.
What I like most about this is it's easier to read/understand what's going on then using a few substring methods.
string str = "832984566";
string val = long.Parse(str).ToString("###-##-####");
There may be a tricky-almost-unreadable regex solution, but this one is pretty readable, and easy.
The first parameter of the .Substring() method is where you start getting the characters, and the second is the number of characters you want to get, and not giving it sets a default as value.length -1 (get chars until the end of the string):
String value = "8329874566";
String Result = value.Substring(0,3) + "-" + value.Substring(3,2) + "-" + value.Substring(6);
--[edit]--
Just noticed you didn't use one of the numbers AT ALL (number '7') in the expected result example you gave, but if you want it, just change the last substring as "5", and if you want the '7' but don't want 5 numbers in the last set, let it like "5,4".
Are you trying to do this like American Social Security numbers? I.e., with a hyphen after the third and and fifth numerals? If so:
string s = "8329874566";
string t = String.Format("{0}-{1}-{2}", s.Substring(0, 3), s.Substring(3, 2), s.Substring(5));
Just out of completeness, a regular expression variant:
Regex.Replace(s, #"(\d{3})(\d{2})(\d{4})", "$1-$2-$3");
I consider the Insert variant to be the cleanest, though.
This works fine, and I think that is more clear:
String value = "8329874566";
value = value.Insert(3, "-").Insert(6, "-");
The console outputs shows this:
832-98-74566
If the hyphens are to go in the same place each time, then you could simply concatenate together the pieces of the orginal string like this:
// 0123456789 <- index
string number = "8329874566";
string new = number.Substring(0, 3) + "-" + number.Substring(3, 2) + "-" + number.Substring(5);
For a general way of making mutable strings, use the StringBuilder class. This allows deletions and insertions to be made before calling ToString to produce the final string.
You could try the following:
string strNumber = "8329874566"
string strNewNumber = strNumber.Substring(0,3) + "-" + strNumber.Substring(4,2) + "-" strNumber.Substring(6)
or something in this manner
string val = "832984566";
string result = String.Format("{0}-{1}-{2}", val.Substring(0,3), val.Substring(3,2), val.Substring(5,4));
var result = string.Concat(value.Substring(0,3), "-", value.Substring(3,2), "-", value.Substring(5,4));
or
var value = "8329874566".Insert(3, "-").Insert(6, "-");
Now how about this for a general solution?
// uglified code to fit within horizontal limits
public static string InsertAtIndices
(this string original, string insertion, params int[] insertionPoints) {
var mutable = new StringBuilder(original);
var validInsertionPoints = insertionPoints
.Distinct()
.Where(i => i >= 0 && i < original.Length)
.OrderByDescending(i => i);
foreach (int insertionPoint in validInsertionPoints)
mutable.Insert(insertionPoint, insertion);
return mutable.ToString();
}
Usage:
string ssn = "832984566".InsertAtIndices("-", 3, 5);
string crazy = "42387542342309856340924803"
.InsertAtIndices(":", 1, 2, 3, 4, 5, 6, 17, 200, -1, -1, 2, 3, 3, 4);
Console.WriteLine(ssn);
Console.WriteLine(crazy);
Output:
832-98-4566
4:2:3:8:7:5:42342309856:340924803
Overkill? Yeah, maybe...
P.S. Yes, I am regex illiterate--something I hope to rectify someday.
A straightforward (but not flexible) approach would be looping over the characters of the string while keeping a counter running. You can then construct a new string character by character. You can add the '-' character after the 3rd and 5th character.
A better approach may be to use a function to insert a single character in the middle of the string at a specific index. String.Insert() would do well. The only thing to pay attention to here is that the string indexes will get off by one with each insert.
EDIT more language-specific as per comments
I want to extract the first folder in the URL below, in this example it is called 'extractThisFolderName' but the folder could have any name and be any length. With this in mind how can I use substring to extract the first folder name?
The string: www.somewebsite.com/extractThisFolderName/leave/this/behind
String folderName = path.Substring(path.IndexOf(#"/"),XXXXXXXXXXX);
It's the length I'm struggling with.
If you're getting a Uri, why not just do uri.Segments[0]?
Or even path.Split(new Char[] { '/' })[1] ?
If you're going to be using each path part, you can use:
String[] parts = path.Split('/');
At which point you can access the "extractThisFolderName" part by accessing parts[1].
Alternatively, you can do this to splice out the foldername:
int firstSlashIndex = path.IndexOf('/');
int secondSlashIndex = path.IndexOf('/', firstSlashIndex + 1);
String folderName = path.Substring(firstSlashIndex + 1, secondSlashIndex - firstSlashIndex);
Daniel's answer gives you other practical ways of doing it. Another alternative using substring:
int start = path.IndexOf('/')+1; // Note that you don't need a verbatim string literal
int secondSlash = path.IndexOf('/', start);
return path.Substring(start, secondSlash-start);
You'll want to add some error checking in there, of course :)
The problem also lends itself to regular expressions. An expression like:
(?<host>.*?)/(?<folder>.*?)/
Is clear about what's going on and you can get the data out by those names.
int start = path.IndexOf('/');
int end = path.IndexOf('/', start + 1);
if (end == -1) end = path.Length;
string folderName = path.Substring(start + 1, end - start - 1);
EDIT: Daniel Schaffer's answer about using uri segments is preferable, but left this in as it may be your path is not really a valid uri.
You could do:
string myStr = "www.somewebsite.com/extractThisFolderName/leave/this/behind";
int startIndex = myStr.IndexOf('/') + 1;
int length = myStr.IndexOf('/', startIndex) - startIndex;
Console.WriteLine(myStr.Substring(startIndex, length));
At the same point I assume this is being done in ASP.Net if so I think there might be another way to get this without doign the querying.
folderName.Split('/')[1]