Replace String in c# - c#

I hava a specific string that I want to replace
string gerneralRootPath = docTab.Rows[0]["URL"].ToString();
string documentName = docTab.Rows[0]["NAME"].ToString();
var connectNamesAndURL = new StringBuilder(gerneralRootPath);
connectNamesAndURL.Remove(30,20);
connectNamesAndURL.Insert(30, documentName);
gerneralRootPath = connectNamesAndURL.ToString();
The output of gerneralRootPath is
"Documents/Z_Documentation/PDF/sales.2010+Implementation+Revised+Feb10.pdf"
The output of is documentName is
"doc123"
My gole is to remove everything after /PDF/.. so that final string looks like this
Documents/Z_Documentation/PDF/doc123
So how can I remove everything after the /PDF/..

Try this
string gerneralRootPath = "Documents/Z_Documentation/PDF/sales.2010+Implementation+Revised+Feb10.pdf";
gerneralRootPath = gerneralRootPath.Remove(gerneralRootPath.IndexOf("PDF") + 3);
gerneralRootPath = gerneralRootPath +"/"+documentName ;

You can achieve this using String.Split() function:
string input = "Documents/Z_Documentation/PDF/sales.2010+Implementation+Revised+Feb10.pdf";
string output = input.Split(new string[] { "/PDF/" }, StringSplitOptions.None).First() + "/PDF/doc123";

using System.IO;
string result = gerneralRootPath.Replace(Path.GetFileName(gerneralRootPath), documentName);
With Path.GetFileName (from System.IO) you get your filename:
sales.2010+Implementation+Revised+Feb10.pdf
The result is:
Documents/Z_Documentation/PDF/doc123

please find the sample code
int i = gerneralRootPath.IndexOf("/PDF/");
if (i >= 0) gerneralRootPath = gerneralRootPath.Substring(0,i+5);
i hope this will help you....

This is an example:
class Program
{
static string RemoveAfterPDF(string gerneralRootPath)
{
string pdf = "PDF";
int index = gerneralRootPath.IndexOf(pdf);
return gerneralRootPath.Substring(0, index + pdf.Length);
}
public static void Main()
{
string test = RemoveAfterPDF("Documents/Z_Documentation/PDF/sales.2010+Implementation+Revised+Feb10.pdf");
}
}
Edit
This is better and much more reusable example:
class Program
{
static string RemoveAfter(string gerneralRootPath, string removeAfter)
{
string result = string.Empty;
int index = gerneralRootPath.IndexOf(removeAfter);
if (index > 0)
result = gerneralRootPath.Substring(0, index + removeAfter.Length);
return result;
}
public static void Main()
{
string test = RemoveAfterPDF("Documents/Z_Documentation/PDF/sales.2010+Implementation+Revised+Feb10.pdf", "PDF");
}
}

Related

How to Get index of a Character in an Unknown Line of a Multiline string in c#

I'm trying to get covid-19 results (only information about Iran) from an Api and show it on a textbox.
and the full result (all countries) that i get from the Api is a json format.
so to get only Iran section i made a Function that loops through lines of the string one by one and check if in that line there is a "{" and if yes get index of that and continue checking if in another line there is a "}" and get index of that too then check if between these, there is "Iran" then add this text (from "{" to "}") in a string:
private string getBetween(string strSourceText, string strStartingPosition, string strEndingPosition)
{
int Starting_CurlyBracket_Index = 0;
int Ending_CurlyBracket_Index = 0;
string FinalText = null;
bool isTurnTo_firstIf = true;
foreach (var line in strSourceText.Split('\r', '\n'))
{
if (isTurnTo_firstIf == true)
{
if (line.Contains(strStartingPosition))
{
Starting_CurlyBracket_Index = line.IndexOf(strStartingPosition); //i think problem is here
isTurnTo_firstIf = false;
}
}
else if (isTurnTo_firstIf == false)
{
if (line.Contains(strEndingPosition))
{
Ending_CurlyBracket_Index = line.IndexOf(strEndingPosition); //i think problem is here
if (strSourceText.Substring(Starting_CurlyBracket_Index, Ending_CurlyBracket_Index - Starting_CurlyBracket_Index).Contains("Iran")) //error here
{
FinalText = strSourceText.Substring(Starting_CurlyBracket_Index, Ending_CurlyBracket_Index - Starting_CurlyBracket_Index);
break;
}
else
{
isTurnTo_firstIf = true;
}
}
}
}
return FinalText;
}
and i call the function like this:
string OnlyIranSection = getBetween(Sorted_Covid19_Result, "{", "}"); //Sorted_Covid19_Result is the full result in json format that converted to string
textBox1.Text = OnlyIranSection;
but i get this Error:
and i know.. its because it gets indexes in the current line but what i need is getting that index in the strSourceText so i can show only this section of the whole result:
USING JSON
As per the comments I read it was really needed to use JSON utility to achieve your needs easier.
You can start with this basic example:
static void Main(string[] args)
{
string jsonString = #"{
""results"": [
{""continent"":""Asia"",""country"":""Indonesia""},
{""continent"":""Asia"",""country"":""Iran""},
{""continent"":""Asia"",""country"":""Philippines""}
]
}";
var result = JsonConvert.DeserializeObject<JsonResult>(jsonString);
var iranInfo = result.InfoList.Where(i => i.Country.ToString() == "Iran").FirstOrDefault();
}
public class JsonResult
{
[JsonProperty("results")]
public List<Info> InfoList { get; set; }
}
public class Info
{
public object Continent { get; set; }
public object Country { get; set; }
}
UPDATE: USING INDEX
As long as the structure of the JSON is consistent always then this kind of sample solution can give you hint.
Console.WriteLine("Original JSON:");
Console.WriteLine(jsonString);
Console.WriteLine();
Console.WriteLine("Step1: Make the json as single line,");
jsonString = jsonString.Replace(" ", "").Replace(Environment.NewLine, " ");
Console.WriteLine(jsonString);
Console.WriteLine();
Console.WriteLine("Step2: Get index of country Iran. And use that index to get the below output using substring.");
var iranIndex = jsonString.ToLower().IndexOf(#"""country"":""iran""");
var iranInitialInfo = jsonString.Substring(iranIndex);
Console.WriteLine(iranInitialInfo);
Console.WriteLine();
Console.WriteLine("Step3: Get inedx of continent. And use that index to get below output using substring.");
var continentIndex = iranInitialInfo.IndexOf(#"""continent"":");
iranInitialInfo = iranInitialInfo.Substring(0, continentIndex-3);
Console.WriteLine(iranInitialInfo);
Console.WriteLine();
Console.WriteLine("Step4: Get the first part of the info by using. And combine it with the initialInfo to bring the output below.");
var beginningIranInfo = jsonString.Substring(0, iranIndex);
var lastOpenCurlyBraceIndex = beginningIranInfo.LastIndexOf("{");
beginningIranInfo = beginningIranInfo.Substring(lastOpenCurlyBraceIndex);
var iranInfo = beginningIranInfo + iranInitialInfo;
Console.WriteLine(iranInfo);
OUTPUT USING INDEX:

Split special string in c#

I want to split the below string with given output.
Can anybody help me to do this.
Examples:
/TEST/TEST123
Output: /Test/
/TEST1/Test/Test/Test/
Output: /Test1/
/Text/12121/1212/
Output: /Text/
/121212121/asdfasdf/
Output: /121212121/
12345
Output: 12345
I have tried string.split function but it is not worked well. Is there any idea or logic that i can implement to achieve this situation.
If the answer in regular expression that would be fine for me.
You simply want the first result of Spiting by /
string output = input.Split('/')[0];
But in case that you have //TEST/ and output should be /TEST you can use regex.
string output = Regex.Matches(input, #"\/?(.+?)\/")[0].Groups[1].Value;
For your 5th case : you have to separate the logic. for example:
public static string Method(string input)
{
var split = input.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
if (split.Length == 0) return input;
return split[0];
}
Or using regex.
public static string Method(string input)
{
var matches = Regex.Matches(input, #"\/?(.+?)\/");
if (matches.Count == 0) return input;
return matches[0].Groups[1].Value;
}
Some results using method:
TEST/54/ => TEST
TEST => TEST
/TEST/ => TEST
I think this would work:
string s1 = "/TEST/TEST123";
string s2 = "/TEST1/Test/Test/Test/";
string s3 = "/Text/12121/1212/";
string s4 = "/121212121/asdfasdf/";
string s5 = "12345";
string pattern = #"\/?[a-zA-Z0-9]+\/?";
Console.WriteLine(Regex.Matches(s1, pattern)[0]);
Console.WriteLine(Regex.Matches(s2, pattern)[0]);
Console.WriteLine(Regex.Matches(s3, pattern)[0]);
Console.WriteLine(Regex.Matches(s4, pattern)[0]);
Console.WriteLine(Regex.Matches(s5, pattern)[0]);
class Program
{
static void Main(string[] args)
{
string example = "/TEST/TEST123";
var result = GetFirstItem(example);
Console.WriteLine("First in the list : {0}", result);
}
static string GetFirstItem(string value)
{
var collection = value?.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
var result = collection[0];
return result;
}
}
StringSplitOptions.RemoveEmptyEntries is an enum which tells the Split function that when it has split the string into an array, if there are elements in the array that are empty strings, the function should not include the empty elements in the results. Basically you want the collection to contain only values.
public string functionName(string input)
{
if(input.Contains('/'))
{
string SplitStr = input.Split('/')[1];
return "/"+SplitStr .Substring(0, 1) +SplitStr.Substring(1).ToLower()+"/"
}
return input;
}
output = (output.Contains("/"))? '/' +input.Split('/')[1]+'/':input;
private void button1_Click(object sender, EventArgs e)
{
string test = #"/Text/12121/1212/";
int first = test.IndexOf("/");
int last = test.Substring(first+1).IndexOf("/");
string finall = test.Substring(first, last+2);
}
i try this code with all your examples and get correct output. try this.
The following method may help you.
public string getValue(string st)
{
if (st.IndexOf('/') == -1)
return st;
return "/" + st.Split('/')[1] + "/";
}

Regex to match particular types of string and replace

I'm having a string with <link rid="bib*">222</link> and <link rid="fig1">333</link>
now i want to replace all the occurance of the above text with rid="bib*", with <CITATION id="CD1">222</CITATION> and replace all the occurance of the text with rid="fig*" , with <FigRef id="fig*">222</FigRef>.
i tried something like this
var reg = new Regex(#"\<link rid=""bib(?<myText>.+?)""\>(?<myText2>.+?)\</link\>$");
but i dont know how to proceed with this and got stuck.
Please help me with this.
Here is a solution based a very similar regex:
private const string REGEX_LINK = #"<link\s+rid=""([^""\d]+)(\d+)"">(.*?)</link>";
private const int REGEX_LINK_GRP_RID_NAME = 1;
private const int REGEX_LINK_GRP_RID_ID = 2;
private const int REGEX_LINK_GRP_VALUE = 3;
static void Main(string[] args)
{
var testInputString = "I'm having a string with <link rid=\"bib123\">222</link> and <link rid=\"fig456\">333</link> now i want to replace all the occurances...";
Regex linkFinder = new Regex(REGEX_LINK, RegexOptions.IgnoreCase);
var result = linkFinder.Replace(testInputString, new MatchEvaluator(LinkMatchEvaluator));
Console.WriteLine(result);
Console.ReadKey();
}
private static string LinkMatchEvaluator(Match m)
{
const string CITATION_RID_NAME = "bib";
const string FIGREF_RID_NAME = "fig";
var ridName = m.Groups[REGEX_LINK_GRP_RID_NAME].Value.ToLower();
var ridID = m.Groups[REGEX_LINK_GRP_RID_ID].Value;
var value = m.Groups[REGEX_LINK_GRP_VALUE].Value;
if (ridName == CITATION_RID_NAME)
{
return String.Format("<CITATION id=\"CD{0}\">{1}</CITATION>", ridID, value);
}
else if (ridName == FIGREF_RID_NAME)
{
return String.Format("<FigRef id=\"fig{0}\">{1}</FigRef>", ridID, value);
}
return m.Value;
}
Thanks for your reply guys. Finally i found the solution for my own question.Now i got the solution for the problem i had. I solved it like this.
public enum intLinks
{
bib = 1,
fig = 2,
tab=3,
tb=4
}
This is the method to replace the content with the matching pattern.
public string NumberedReplaceTest(string input, intLinks refToFind)
{
//"<link rid=\"bib1\">1</link>"
Regex regex = new Regex(#"<link rid=""" + refToFind.ToString() + #"(?<sequence>\d*)"">(\r?\n)*(?<number>[a-zA-Z0-9]*)(\r?\n)*</link>");
if (!regex.IsMatch(input))
return input;
switch (refToFind)
{
case intLinks.bib: return regex.Replace(input, "<Citation CID=\"CR${sequence}\">${number}</Citation>");
case intLinks.fig: return regex.Replace(input, "<InternalRef RefID=\"Fig${sequence}\">${number}</InternalRef>");
case intLinks.tab: return regex.Replace(input, "<InternalRef RefID=\"Tab${sequence}\">${number}</InternalRef>");
case intLinks.tb: return regex.Replace(input, "<InternalRef RefID=\"Tab${sequence}\">${number}</InternalRef>");
default: return input;
}
}
I'm calling the method like this.
bodyString = NumberedReplaceTest(bodyString,intLinks.bib);
bodyString = NumberedReplaceTest(bodyString, intLinks.fig);
bodyString = NumberedReplaceTest(bodyString, intLinks.tab);
bodyString = NumberedReplaceTest(bodyString, intLinks.tb);`

How to efficiently remove a query string by Key from a Url?

How to remove a query string by Key from a Url?
I have the below method which works fine but just wondering is there any better/shorter way? or a built-in .NET method which can do it more efficiently?
public static string RemoveQueryStringByKey(string url, string key)
{
var indexOfQuestionMark = url.IndexOf("?");
if (indexOfQuestionMark == -1)
{
return url;
}
var result = url.Substring(0, indexOfQuestionMark);
var queryStrings = url.Substring(indexOfQuestionMark + 1);
var queryStringParts = queryStrings.Split(new [] {'&'});
var isFirstAdded = false;
for (int index = 0; index <queryStringParts.Length; index++)
{
var keyValue = queryStringParts[index].Split(new char[] { '=' });
if (keyValue[0] == key)
{
continue;
}
if (!isFirstAdded)
{
result += "?";
isFirstAdded = true;
}
else
{
result += "&";
}
result += queryStringParts[index];
}
return result;
}
For example I can call it like:
Console.WriteLine(RemoveQueryStringByKey(#"http://www.domain.com/uk_pa/PostDetail.aspx?hello=hi&xpid=4578", "xpid"));
Hope the question is clear.
Thanks,
This works well:
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url);
// this gets all the query string key value pairs as a collection
var newQueryString = HttpUtility.ParseQueryString(uri.Query);
// this removes the key if exists
newQueryString.Remove(key);
// this gets the page path from root without QueryString
string pagePathWithoutQueryString = uri.GetLeftPart(UriPartial.Path);
return newQueryString.Count > 0
? String.Format("{0}?{1}", pagePathWithoutQueryString, newQueryString)
: pagePathWithoutQueryString;
}
an example:
RemoveQueryStringByKey("https://www.google.co.uk/search?#hl=en&output=search&sclient=psy-ab&q=cookie", "q");
and returns:
https://www.google.co.uk/search?#hl=en&output=search&sclient=psy-ab
var queryString = "hello=hi&xpid=4578";
var qs = System.Web.HttpUtility.ParseQueryString(queryString);
qs.Remove("xpid");
var newQuerystring = qs.ToString();
This still works in .NET 5.
There's a useful class called UriBuilder in the System namespace. We can use it along with a couple of extension methods to do the following:
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
u = u.DropQueryItem("key1");
Or like this:
Uri u = new Uri("http://example.com?key1=value1&key2=value2");
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem("key1");
u = b.Uri;
The extension methods:
using System;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
public static class UriExtensions
{
public static Uri DropQueryItem(this Uri u, string key)
{
UriBuilder b = new UriBuilder(u);
b.RemoveQueryItem(key);
return b.Uri;
}
}
public static class UriBuilderExtensions
{
private static string _ParseQueryPattern = #"(?<key>[^&=]+)={0,1}(?<value>[^&]*)";
private static Regex _ParseQueryRegex = null;
private static Regex ParseQueryRegex
{
get
{
if (_ParseQueryRegex == null)
{
_ParseQueryRegex = new Regex(_ParseQueryPattern, RegexOptions.Compiled | RegexOptions.Singleline);
}
return _ParseQueryRegex;
}
}
public static void SetQueryItem(this UriBuilder b, string key, string value)
{
NameValueCollection parms = ParseQueryString(b.Query);
parms[key] = value;
b.Query = RenderQuery(parms);
}
public static void RemoveQueryItem(this UriBuilder b, string key)
{
NameValueCollection parms = ParseQueryString(b.Query);
parms.Remove(key);
b.Query = RenderQuery(parms);
}
private static string RenderQuery(NameValueCollection parms)
{
StringBuilder sb = new StringBuilder();
for (int i=0; i<parms.Count; i++)
{
string key = parms.Keys[i];
sb.Append(key + "=" + parms[key]);
if (i < parms.Count - 1)
{
sb.Append("&");
}
}
return sb.ToString();
}
public static NameValueCollection ParseQueryString(string query, bool caseSensitive = true)
{
NameValueCollection pairs = new NameValueCollection(caseSensitive ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase);
string q = query.Trim().TrimStart(new char[] {'?'});
MatchCollection matches = ParseQueryRegex.Matches(q);
foreach (Match m in matches)
{
string key = m.Groups["key"].Value;
string value = m.Groups["value"].Value;
if (pairs[key] != null)
{
pairs[key] = pairs[key] + "," + value;
}
else
{
pairs[key] = value;
}
}
return pairs;
}
}
I know this is a rather old question, but everything I read felt a bit complicated.
public Uri GetUriWithoutQueryParam( Uri originalUri, string paramKey ) {
NameValueCollection newQuery = HttpUtility.ParseQueryString( originalUri.Query );
newQuery.Remove( paramKey );
return new UriBuilder( originalUri ) { Query = newQuery.ToString() }.Uri;
}
We can also do it using regex
string queryString = "Default.aspx?Agent=10&Language=2"; //Request.QueryString.ToString();
string parameterToRemove="Language"; //parameter which we want to remove
string regex=string.Format("(&{0}=[^&\s]+|(?<=\?){0}=[^&\s]+&?)",parameterToRemove); //this will not work for javascript, for javascript you can do following
string finalQS = Regex.Replace(queryString, regex, "");
//javascript(following is not js syntex, just want to give idea how we can able do it in js)
string regex1 = string.Format("(&{0}=[^&\s]+)",parameterToRemove);
string regex2 = string.Format("(\?{0}=[^&\s]+&?)",parameterToRemove);
string finalQS = Regex.Replace(queryString, regex1, "").Replace(queryString, regex2, "");
https://regexr.com/3i9vj
How about this:
string RemoveQueryStringByKey(string url, string key)
{
string ret = string.Empty;
int index = url.IndexOf(key);
if (index > -1)
{
string post = string.Empty;
// Find end of key's value
int endIndex = url.IndexOf('&', index);
if (endIndex != -1) // Last query string value?
{
post = url.Substring(endIndex, url.Length - endIndex);
}
// Decrement for ? or & character
--index;
ret = url.Substring(0, index) + post;
}
return ret;
}
I found a way without using Regex:
private string RemoveQueryStringByKey(string sURL, string sKey) {
string sOutput = string.Empty;
int iQuestion = sURL.IndexOf('?');
if (iQuestion == -1) return (sURL);
int iKey = sURL.Substring(iQuestion).IndexOf(sKey) + iQuestion;
if (iKey == -1) return (sURL);
int iNextAnd = sURL.Substring(iKey).IndexOf('&') + iKey + 1;
if (iNextAnd == -1) {
sOutput = sURL.Substring(0, iKey - 1);
}
else {
sOutput = sURL.Remove(iKey, iNextAnd - iKey);
}
return (sOutput);
}
I did try this with adding another field at the end, and it works fine for that too.
I'm thinking the shortest way (that I believe produces a valid URL in all cases, assuming the URL was valid to begin with) would be to use this regex (where getRidOf is the variable name you are trying to remove) and the replacement is a zero-length string ""):
(?<=[?&])getRidOf=[^&]*(&|$)
or maybe even
\bgetRidOf=[^&]*(&|$)
while possibly not the absolute prettiest URLs, I think they are all valid:
INPUT OUTPUT
----------- ------------
blah.com/blah.php?getRidOf=d.co&blah=foo blah.com/blah.php?blah=foo
blah.com/blah.php?f=0&getRidOf=d.co&blah=foo blah.com/blah.php?f=0&blah=foo
blah.com/blah.php?hello=true&getRidOf=d.co blah.com/blah.php?hello=true&
blah.com/blah.php?getRidOf=d.co blah.com/blah.php?
and it's a simple regex replace:
Dim RegexObj as Regex = New Regex("(?<=[?&])getRidOf=[^&]*(&|$)")
RegexObj.Replace("source.url.com/find.htm?replace=true&getRidOf=PLEASE!!!", "")
...should result in the string:
"source.url.com/find.htm?replace=true&"
...which seems to be valid for an ASP.Net application, while replace does equal true (not true& or anything like that)
I'll try to adapt it if you have a case where it won't work :)
public static string RemoveQueryStringByKey(string sURL, string sKey)
{
string sOutput = string.Empty;
string sToReplace = string.Empty;
int iFindTheKey = sURL.IndexOf(sKey);
if (iFindTheKey == -1) return (sURL);
int iQuestion = sURL.IndexOf('?');
if (iQuestion == -1) return (sURL);
string sEverythingBehindQ = sURL.Substring(iQuestion);
List<string> everythingBehindQ = new List<string>(sEverythingBehindQ.Split('&'));
foreach (string OneParamPair in everythingBehindQ)
{
int iIsKeyInThisParamPair = OneParamPair.IndexOf(sKey);
if (iIsKeyInThisParamPair != -1)
{
sToReplace = "&" + OneParamPair;
}
}
sOutput = sURL.Replace(sToReplace, "");
return (sOutput);
}
Below code before deleting your QueryString.
PropertyInfo isreadonly =
typeof(System.Collections.Specialized.NameValueCollection).GetProperty(
"IsReadOnly", BindingFlags.Instance | BindingFlags.NonPublic);
// make collection editable
isreadonly.SetValue(this.Request.QueryString, false, null);
// remove
this.Request.QueryString.Remove("yourKey");
Sorry this is a bit dirty but should work in older framework
public String RemoveQueryString( String rawUrl , String keyName)
{
var currentURL_Split = rawUrl.Split('&').ToList();
currentURL_Split = currentURL_Split.Where(o => !o.ToLower().StartsWith(keyName.ToLower()+"=")).ToList();
String New_RemovedKey = String.Join("&", currentURL_Split.ToArray());
New_RemovedKey = New_RemovedKey.Replace("&&", "&");
return New_RemovedKey;
}
Here is my solution:
I'v added some extra input validation.
public static void TryRemoveQueryStringByKey(ref string url, string key)
{
if (string.IsNullOrEmpty(url) ||
string.IsNullOrEmpty(key) ||
Uri.IsWellFormedUriString(url, UriKind.RelativeOrAbsolute) == false)
{
return false;
}
try
{
Uri uri = new Uri(url);
// This gets all the query string key value pairs as a collection
NameValueCollection queryCollection = HttpUtility.ParseQueryString(uri.Query);
string keyValue = queryCollection.Get(key);
if (url.IndexOf("&" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0)
{
url = url.Replace("&" + key + "=" + keyValue, String.Empty);
return true;
}
else if (url.IndexOf("?" + key + "=" + keyValue, StringComparison.OrdinalIgnoreCase) >= 0)
{
url = url.Replace("?" + key + "=" + keyValue, String.Empty);
return true;
}
else
{
return false;
}
}
catch
{
return false;
}
}
Some unit testing examples:
string url1 = "http://www.gmail.com?a=1&cookie=cookieValue"
Assert.IsTrue(TryRemoveQueryStringByKey(ref url1,"cookie")); //OUTPUT: "http://www.gmail.com?a=1"
string url2 = "http://www.gmail.com?cookie=cookieValue"
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com"
string url3 = "http://www.gmail.com?cookie="
Assert.IsTrue(TryRemoveQueryStringByKey(ref url2,"cookie")); //OUTPUT: "http://www.gmail.com"
Here's a full solution that works with >= 0 params specified, and any form of URL:
/// <summary>
/// Given a URL in any format, return URL with specified query string param removed if it exists
/// </summary>
public static string StripQueryStringParam(string url, string paramToRemove)
{
return StripQueryStringParams(url, new List<string> {paramToRemove});
}
/// <summary>
/// Given a URL in any format, return URL with specified query string params removed if it exists
/// </summary>
public static string StripQueryStringParams(string url, List<string> paramsToRemove)
{
if (paramsToRemove == null || !paramsToRemove.Any()) return url;
var splitUrl = url.Split('?');
if (splitUrl.Length == 1) return url;
var urlFirstPart = splitUrl[0];
var urlSecondPart = splitUrl[1];
// Even though in most cases # isn't available to context,
// we may be passing it in explicitly for helper urls
var secondPartSplit = urlSecondPart.Split('#');
var querystring = secondPartSplit[0];
var hashUrlPart = string.Empty;
if (secondPartSplit.Length > 1)
{
hashUrlPart = "#" + secondPartSplit[1];
}
var nvc = HttpUtility.ParseQueryString(querystring);
if (!nvc.HasKeys()) return url;
// Remove any matches
foreach (var key in nvc.AllKeys)
{
if (paramsToRemove.Contains(key))
{
nvc.Remove(key);
}
}
if (!nvc.HasKeys()) return urlFirstPart;
return urlFirstPart +
"?" + string.Join("&", nvc.AllKeys.Select(c => c.ToString() + "=" + nvc[c.ToString()])) +
hashUrlPart;
}
A more modern answer for this old question in case someone else stumbles across it like I did.
This is using the Uri class to parse the URL (can be skipped if your URL is already in a Uri object) and LINQ to filter the query string.
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url, UriKind.Absolute);
var queryParts = uri.Query
.TrimStart('?')
.Split('&')
.Where(item => string.CompareOrdinal(item, key) != 0);
return uri.Scheme + Uri.SchemeDelimiter
+ uri.Authority
+ uri.AbsolutePath
+ "?" + string.Join("&", queryParts);
}
With reusing the signature from the accepted answer, but preserving the fragment and using QueryHelpers from Microsoft.AspNetCore.WebUtilities.
public static string RemoveQueryStringByKey(string url, string key)
{
var uri = new Uri(url);
var newQueryString = QueryHelpers.ParseQuery(uri.Query);
if (newQueryString.Remove(key))
{
var urlWithNewQuery = QueryHelpers.AddQueryString(
uri.GetLeftPart(UriPartial.Path),
newQueryString.ToDictionary(
queryParam => queryParam.Key,
queryParam => queryParam.Value.ToString()))
return $"{urlWithNewQuery}{uri.Fragment}";
}
return url;
}
string url = HttpContext.Current.Request.Url.AbsoluteUri;
string[] separateURL = url.Split('?');
NameValueCollection queryString = System.Web.HttpUtility.ParseQueryString(separateURL[1]);
queryString.Remove("param_toremove");
string revisedurl = separateURL[0] + "?" + queryString.ToString();

C#: Get first directory name of a relative path

How to get the first directory name in a relative path, given that they can be different accepted directory separators?
For example:
foo\bar\abc.txt -> foo
bar/foo/foobar -> bar
Works with both forward and back slash
static string GetRootFolder(string path)
{
while (true)
{
string temp = Path.GetDirectoryName(path);
if (String.IsNullOrEmpty(temp))
break;
path = temp;
}
return path;
}
Seems like you could just use the string.Split() method on the string, then grab the first element.
example (untested):
string str = "foo\bar\abc.txt";
string str2 = "bar/foo/foobar";
string[] items = str.split(new char[] {'/', '\'}, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(items[0]); // prints "foo"
items = str2.split(new char[] {'/', '\'}, StringSplitOptions.RemoveEmptyEntries);
Console.WriteLine(items[0]); // prints "bar"
The most robust solution would be to use DirectoryInfo and FileInfo. On a Windows NT-based system it should accept either forward or backslashes for separators.
using System;
using System.IO;
internal class Program
{
private static void Main(string[] args)
{
Console.WriteLine(GetTopRelativeFolderName(#"foo\bar\abc.txt")); // prints 'foo'
Console.WriteLine(GetTopRelativeFolderName("bar/foo/foobar")); // prints 'bar'
Console.WriteLine(GetTopRelativeFolderName("C:/full/rooted/path")); // ** throws
}
private static string GetTopRelativeFolderName(string relativePath)
{
if (Path.IsPathRooted(relativePath))
{
throw new ArgumentException("Path is not relative.", "relativePath");
}
FileInfo fileInfo = new FileInfo(relativePath);
DirectoryInfo workingDirectoryInfo = new DirectoryInfo(".");
string topRelativeFolderName = string.Empty;
DirectoryInfo current = fileInfo.Directory;
bool found = false;
while (!found)
{
if (current.FullName == workingDirectoryInfo.FullName)
{
found = true;
}
else
{
topRelativeFolderName = current.Name;
current = current.Parent;
}
}
return topRelativeFolderName;
}
}
Based on the answer provided by Hasan Khan ...
private static string GetRootFolder(string path)
{
var root = Path.GetPathRoot(path);
while (true)
{
var temp = Path.GetDirectoryName(path);
if (temp != null && temp.Equals(root))
break;
path = temp;
}
return path;
}
This will give the the top level folder
Based on the question you ask, the following should work:
public string GetTopLevelDir(string filePath)
{
string temp = Path.GetDirectoryName(filePath);
if(temp.Contains("\\"))
{
temp = temp.Substring(0, temp.IndexOf("\\"));
}
else if (temp.Contains("//"))
{
temp = temp.Substring(0, temp.IndexOf("\\"));
}
return temp;
}
When passed foo\bar\abc.txt it will foo as wanted- same for the / case
Here is another example in case your path if following format:
string path = "c:\foo\bar\abc.txt"; // or c:/foo/bar/abc.txt
string root = Path.GetPathRoot(path); // root == c:\
This should work fine
string str = "foo\bar\abc.txt";
string str2 = "bar/foo/foobar";
str.Replace("/", "\\").Split('\\').First(); // foo
str2.Replace("/", "\\").Split('\\').First(); // bar
Here my example, with no memory footprint (without creating new strings in memory):
var slashIndex = relativePath.IndexOf('/');
var backslashIndex = relativePath.IndexOf('\\');
var firstSlashIndex = (slashIndex > 0) ? (slashIndex < backslashIndex ? slashIndex : (backslashIndex == -1) ? slashIndex : backslashIndex) : backslashIndex;
var rootDirectory = relativePath.Substring(0, firstSlashIndex);

Categories

Resources