I need to extract the rest of the portion of the URL after "home"
for example the URLs can be
https://www.example.com/site/country/home/products
https://www.example.com/site/country/home/products/consumer
https://www.example.com/site/country/home/products/consumer/kids
The keywords in the url "site", "country" might change.
All I need in the output is:
/products
/products/consumer
/products/consumer/kids
I tried using Regex, but didn't worked in above situation
As suggested by Corion and David in the comments, in this case, the simplest method is probably just to find the index of /home/ and then strip everything up to that point (but not second /):
string home = "/home/";
int homeIndex = url.IndexOf(home);
string relativeUrl = url.Substring(homeIndex + home.Length - 1);
Using a regular expression, you want to match the /home/ substring, and capture the second / and everything following it:
Match match = Regex.Match(url, #"/home(/.*)");
string relativeUrl = "/";
if (match.Success) {
relativeUrl = match.Groups[1].Value;
}
its a so simple c# code i think it may help you
string sub = "https://www.example.com/site/country/home/products";
string temp = "";
string[] ss = sub.Split('/');
for(int i = 0; i < sub.Length; i++)
{
if (ss[i] == "home")
{
i++;
for (int j = i; j < ss.Length; j++)
temp +='/'+ ss[j];
break;
}
}
Console.WriteLine(temp);
You could use the System.Uri class to extract the segments of the URL:
Uri link = new Uri("https://www.example.com/site/country/home/products/consumer/kids");
string[] segs = link.Segments;
int idxOfHome = Array.IndexOf(segs, "home/");
string restOfUrl = string.Join("", segs, idxOfHome+1, segs.Length - (idxOfHome + 1));
Yeilds:
products/consumer/kids
It is easy using Regex. Please use the following Regex and test your scenario. It works fine.
Regex: '(?<=\/home).*\b'
No need to worry about front portion before home. As soon as it finds home, it will take words after home.
Related
I'm searching for a solution to this case:
I have a Method inside a DLL that receive a string that contains some words as "placeholders/parameters" that will be replaced by a result of another specific method (inside dll too)
Too simplificate: It's a query string received as an argument to be on a method inside a DLL, where X word that matchs a specifc case, will be replaced.
My method receive a string that could be like this:
(on .exe app)
string str = "INSERT INTO mydb.mytable (id_field, description, complex_number) VALUES ('#GEN_COMPLEX_ID#','A complex solution', '#GEN_COMPLEX_ID#');"
MyDLLClass.MyMethod(str);
So, the problem is: if i replace the #GEN_COMPLEX_ID# on this string, wanting that a different should be on each match, it not will happen because the replaced executes the function in a single shot (not step by step). So, i wanna help to implement this: a step by step replace of any text (like Find some word, replace, than next ... replace ... next... etc.
Could you help me?
Thanks!
This works pretty well for me:
string yourOriginalString = "ab cd ab cd ab cd";
string pattern = "ab";
string yourNewDescription = "123";
int startingPositionOffset = 0;
int yourOriginalStringLength = yourOriginalString.Length;
MatchCollection match = Regex.Matches(yourOriginalString, pattern, RegexOptions.IgnoreCase | RegexOptions.Multiline);
foreach (Match m in match)
{
yourOriginalString = yourOriginalString.Substring(0, m.Index+startingPositionOffset) + yourNewDescription + yourOriginalString.Substring(m.Index + startingPositionOffset+ m.Length);
startingPositionOffset = yourOriginalString.Length - yourOriginalStringLength;
}
If what you're asking is how to replace each placeholder with a different value, you can do it using the Regex.Replace overload which accepts a MatchEvaluator delegate, and executes it for each match:
// conceptually, something like this (note that it's not checking if there are
// enough values in the replacementValues array)
static string ReplaceMultiple(
string input, string placeholder, IEnumerable<string> replacementValues)
{
var enumerator = replacementValues.GetEnumerator();
return Regex.Replace(input, placeholder,
m => { enumerator.MoveNext(); return enumerator.Current; });
}
This is, of course, presuming that all placeholders look the same.
Pseudo-code
var split = source.Split(placeholder); // create array of items without placeholders
var result = split[0]; // copy first item
for(int i = 1; i < result.Length; i++)
{
bool replace = ... // ask user
result += replace ? replacement : placeholder; // to put replacement or not to put
result += split[i]; // copy next item
}
you should use the split method like this
string [] placeholder = {"#Placeholder#"} ;
string[] request = cd.Split(placeholder, StringSplitOptions.RemoveEmptyEntries);
StringBuilder requetBuilding = new StringBuilder();
requetBuilding.Append(request[0]);
int index = 1;
requetBuilding.Append("Your place holder replacement");
requetBuilding.Append(request[index]);
index++; //next replacement
// requetBuilding.Append("Your next place holder replacement");
// requetBuilding.Append(request[index]);
In my code behind in C# I have the following code. How do I change the replace so that only
the first occurance of www is replaced?
For example if the User enters www.testwww.com then I should be saving it as testwww.com.
Currently as per the below code it saves as www.com (guess due to substr code).
Please help. Thanks in advance.
private string FilterUrl(string url)
{
string lowerCaseUrl = url.ToLower();
lowerCaseUrl = lowerCaseUrl.Replace("http://", string.Empty).Replace("https://", string.Empty).Replace("ftp://", string.Empty);
lowerCaseUrl = lowerCaseUrl.Replace("www.", string.Empty);
string lCaseUrl = url.Substring(url.Length - lowerCaseUrl.Length, lowerCaseUrl.Length);
return lCaseUrl;
}
As Ally suggested. You are much better off using System.Uri. This also replaces the leading www as you wish.
private string FilterUrl(string url)
{
Uri uri = new UriBuilder(url).Uri; // defaults to http:// if missing
return Regex.Replace(uri.Host, "^www.", "") + uri.PathAndQuery;
}
Edit: The trailing slash is because of the PathAndQuery property. If there was no path you are left with the slash only. Just add another regex replace or string replace. Here's the regex way.
return Regex.Replace(uri.Host, "^www.", "") + Regex.Replace(uri.PathAndQuery, "/$", "");
I would suggest using indexOf(string) to find the first occurrence.
Edit: okay someone beat me to it ;)
You could use IndexOf like Felipe suggested OR do it the low tech way..
lowerCaseUrl = lowerCaseUrl.Replace("http://", string.Empty).Replace("https://", string.Empty).Replace("ftp://", string.Empty).Replace("http://www.", string.Empty).Replace("https://www.", string.Empty)
Would be interested to know what you're trying to achieve.
Came up with a cool static method, also works for replacing the first x occurrences:
public static string ReplaceOnce(this string s, string replace, string with)
{
return s.ReplaceCount(replace, with);
}
public static string ReplaceCount(this string s, string replace, string with, int howManytimes = 1)
{
if (howManytimes < 0) throw InvalidOperationException("can not replace a string less than zero times");
int count = 0;
while (s.Contains(replace) && count < howManytimes)
{
int position = s.IndexOf(replace);
s = s.Remove(position, replace.Length);
s = s.Insert(position, with);
count++;
}
return s;
}
The ReplaceOnce isn't necessary, just a simplifier. Call it like this:
string url = "http://www.stackoverflow.com/questions/www/www";
var urlR1 - url.ReplaceOnce("www", "xxx");
// urlR1 = "http://xxx.stackoverflow.com/questions/www/www";
var urlR2 - url.ReplaceCount("www", "xxx", 2);
// urlR2 = "http://xxx.stackoverflow.com/questions/xxx/www";
NOTE: this is case-sensitive as it is written
The Replace method will change all content of the string. You have to locate the piece you want to remove using IndexOf method, and remove using Remove method of string. Try something like this:
//include the namespace
using System.Globalization;
private string FilterUrl(string url)
{
// ccreate a Comparer object.
CompareInfo myCompare = CultureInfo.InvariantCulture.CompareInfo;
// find the 'www.' on the url parameter ignoring the case.
int position = myCompare.IndexOf(url, "www.", CompareOptions.IgnoreCase);
// check if exists 'www.' on the string.
if (position > -1)
{
if (position > 0)
url = url.Remove(position - 1, 5);
else
url = url.Remove(position, 5);
}
//if you want to remove http://, https://, ftp://.. keep this line
url = url.Replace("http://", string.Empty).Replace("https://", string.Empty).Replace("ftp://", string.Empty);
return url;
}
Edits
There was a part in your code that is removing a piece of string. If you just want to remove the 'www.' and 'http://', 'https://', 'ftp://', take a look the this code.
This code also ignore the case when it compares the url parameter and what you have been findind, on case, 'www.'.
http://www.test.com/test.aspx?testinfo=&|&
I am trying to replace & with values from a table. I got name and age as two paramaters that I need to substitue and get url like this:
http://www.test.com/test.aspx?testinfo=name|age
If I have 3 string parameters to be replaced for a url:
http://www.test.com/test.aspx?testinfo=&|&
Viz name, age, address for the above url:
http://www.test.com/test.aspx?testinfo=name|age|address
string URL=string.Empty;
URL=http://www.test.com/test.aspx?testinfo=&|&;
//in this case fieldsCount is 2, ie. name and age
for(int i=0; i<fieldsCount.Length-1;i++)
{
URL.Replace("*","name");
}
How do I add "age" so that I get ? any inputs will be helpful.
http://www.test.com/test.aspx?testinfo=name|age
I think this is what you want,
List<string> keys = new List<string>() { "name", "age", "param3" };
string url = "http://www.test.com/test.aspx?testinfo=&|&;";
Regex reg = new Regex("&");
int count = url.Count(p => p == '&');
for (int i = 0; i < count; i++)
{
if (i >= keys.Count)
break;
url = reg.Replace(url, keys[i], 1);
}
I'm curious about two things.
Why are you using & as something to replace, when this has contextual
meaning within the query string as a delimiter between key/value
pairs?
Why does your string have just 2 fields (&|&), when sometimes
the value to replace it with has more than 2 keys?
If these things don't matter, it would make more sense to me to have a replacement string of something else... for instance http://www.test.com/test.aspx?testinfo=[testinfo]. Of course, you need to choose something that has 0 chance of showing up in your Url apart from where you expect it. You can then replace it with something like the following:
url = url.Replace("[testinfo]", string.Join("|", fieldsCount));
Note that this doesn't require your for-loop, and should result in your expected url.
See string.Join on msdn.
Concatenates all the elements of a string array, using the specified
separator between each element.
If I understood right, I think you need something like this:
private static string SubstituteAmpersands(string url, string[] substitutes)
{
StringBuilder result = new StringBuilder();
int substitutesIndex = 0;
foreach (char c in url)
{
if (c == '&' && substitutesIndex < substitutes.Length)
result.Append(substitutes[substitutesIndex++]);
else
result.Append(c);
}
return result.ToString();
}
I would like to remove the last segment of Request.Url, so for instance...
http://www.example.com/admin/users.aspx/deleteUser
would change to
http://www.example.com/admin/users.aspx
I would prefer linq but accept any solution that efficiently works.
Use the Uri class to parse the URI - you can access all the segments using the Segments property and rebuild the URI without the last segment.
var uri = new Uri(myString);
var noLastSegment = string.Format("{0}://{1}", uri.Scheme, uri.Authority);
for(int i = 0; i < uri.Segments.Length - 1; i++)
{
noLastSegment += uri.Segments[i];
}
noLastSegment = noLastSegment.Trim("/".ToCharArray()); // remove trailing `/`
As an alternative to getting the scheme and host name, as suggested by Dour High Arch in his comment:
var noLastSegment = uri.GetComponents(UriComponents.SchemeAndServer,
UriFormat.SafeUnescaped);
Much the same as #Oded's answer, but using a UriBuilder instead:
var uri = new Uri("http://www.example.com/admin/users.aspx/deleteUser");
var newSegments = uri.Segments.Take(uri.Segments.Length - 1).ToArray();
newSegments[newSegments.Length-1] =
newSegments[newSegments.Length-1].TrimEnd('/');
var ub=new UriBuilder(uri);
ub.Path=string.Concat(newSegments);
//ub.Query=string.Empty; //maybe?
var newUri=ub.Uri;
To remove the last segment of Request.Url it is enough to subtract from absolute uri the length of last segment.
string uriWithoutLastSegment = Request.Url.AbsoluteUri.Remove(
Request.Url.AbsoluteUri.Length - Request.Url.Segments.Last().Length );
I find manipulating Uri's fairly annoying, and as the other answers are quite verbose, here's my two cents in the form of an extension method.
As a bonus you also get a replace last segement method. Both methods will leave querystring and other parts of the url intact.
public static class UriExtensions
{
private static readonly Regex LastSegmentPattern =
new Regex(#"([^:]+://[^?]+)(/[^/?#]+)(.*$)", RegexOptions.Compiled | RegexOptions.IgnoreCase);
public static Uri ReplaceLastSegement(this Uri me, string replacement)
=> me != null ? new Uri(LastSegmentPattern.Replace(me.AbsoluteUri, $"$1/{replacement}$3")) : null;
public static Uri RemoveLastSegement(this Uri me)
=> me != null ? new Uri(LastSegmentPattern.Replace(me.AbsoluteUri, "$1$3")) : null;
}
Well the trivial solution would be to iterate char by char from the end of the string towards its beginning and search for the first '/' to come (I guess that also came into your mind).
Try this:
string url = "http://www.example.com/admin/users.aspx/deleteUser";
for (int i = url.Length - 1; i >= 0; i--) {
if (url[i] == '/') return url.Substring(0, i - 1);
}
I have a string like this:
"http://localhost:55164/Images/photos/2/2.jpg"
I need to retrieve the filename and the 2 out of the /2/ and put them into their own strings. I've been messing around with StringBuilder and replace and substr to no avail since the filename length is variable. Anyone have a quick way to do this?
Thanks
string link = "http://localhost:55164/Images/photos/2/2.jpg"; // your link
string[] x = link.Split('/'); // split it into pieces at the slash
string filename = (x.Length >= 1) ? x[x.Length - 1] : null; // get the last part
string dir = (x.Length >= 2) ? x[x.Length - 2] : null; // get the 2nd last part
Edit, checked the array length before trying to access it's pieces like someone suggested below in the comments.
You could cheat and use the Path class. This is easier and adds extra readability at the same time.
string path = "http://localhost:55164/Images/photos/2/2.jpg";
Console.WriteLine(Path.GetFileName(path));
string[] dirSplit = Path.GetDirectoryName(path).Split('\\');
Console.WriteLine(dirSplit[dirSplit.Length - 1]);
I would suggest using the Path class:
string filename = Path.GetFileName(s);
string dir = Path.GetDirectoryName(s).GetFileName(s);
One quick way you could do with would be to split the string by the forward slash.
In this way you'll know that the last item in the array and the second-to-last item will be what you require.
Such that:
string url = "http://localhost:55164/Images/photos/2/2.jpg";
string[] urlParts = url.Split('/');
string file = urlParts[urlParts.length -1];
use Split function with '/' as separator and take 2 last elements of the array.
string s = "";
string[] arr = s.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string ans = "";
if (arr.Length > 1)
ans = arr[arr.Length - 1] + arr[arr.Length - 2];
I suggest you use the System.Uri class which is tailor-made for this purpose (providing easy access to parts of a URI), e.g.,
Uri uri = new Uri("http://localhost:55164/Images/photos/2/2.jpg");
string[] segments = uri.Segments;
foreach (string segment in segments)
{
Console.WriteLine(segment.Trim('/'));
}