Remove characters in string? - c#

Here is my string:
[{"url":"http:\/\/is1.mzstatic.com\/image\/thumb\/Music6\/v4\/47\/20\/1f\/47201fb7-ddbf-2ff9-767d-4e26065d0158\/source\/600x600bb.jpg"
Here is what I need:
http:\/\/is1.mzstatic.com\/image\/thumb\/Music6\/v4\/47\/20\/1f\/47201fb7-ddbf-2ff9-767d-4e26065d0158\/source\/600x600bb.jpg
I am positive I use the following to remove the quotation marks:
s = s.Replace("\"", "");
But how would I remove:
[{"url":
I think I would use something like:
int index = sourceString.IndexOf(removeString);
string cleanPath = (index < 0)
? sourceString
: sourceString.Remove(index, removeString.Length);
but for some reason I cannot add it to here due to it itself using double quotes.

Assuming you aren't using any JSON libraries and just getting the property url value then why not keep it simple with string.IndexOf() and ignore the first and last char?
var idx = rawJSON.IndexOf(':');
if ( idx > -1 )
{
return rawJSON.SubString(idx + 2, rawJSON.Length - (idx + 2 + 1)); //calculating in my head....
}
else
{
return rawJSON;
}

This works a treat:
var s = #"[{""url"":""http:\/\/is1.mzstatic.com\/image\/thumb\/Music6\/v4\/47\/20\/1f\/47201fb7-ddbf-2ff9-767d-4e26065d0158\/source\/600x600bb.jpg""}]";
var jarray = Newtonsoft.Json.JsonConvert.DeserializeObject(s) as Newtonsoft.Json.Linq.JArray;
var url = jarray[0].Value<string>("url");
I get:
http://is1.mzstatic.com/image/thumb/Music6/v4/47/20/1f/47201fb7-ddbf-2ff9-767d-4e26065d0158/source/600x600bb.jpg
You just need to NuGet "Newtonsoft.Json" to get the library in.

You can use Replace() again on your [{"url":, just remember that you removed the " on the first Replace, so it is now only [{url:
s = s.Replace("\"","");
s = s.Replace("[{url:", ""); // s no longer has " after the first Replace

Related

Can't properly rebuild a string with Replacement values from Dictionary

I am trying to build a file using a template. I am processing the file in a while loop line by line. The first section of the file, first 35 lines are header information. The infromation is surrounded by # signs. Take this string for example:
Field InspectionStationID 3 {"PVA TePla #WSM#", "sw#data.tool_context.TOOL_SOFTWARE_VERSION#", "#data.context.TOOL_ENTITY#"}
The expected output should be:
Field InspectionStationID 3 {"PVA TePla", "sw0.2.002", "WSM102"}
This header section uses a different mapping than the rest of the file so I wanted to parse the file line by line from top to bottom and use a different logic for each section so that I don't waste time parsing the entire file at once multiple times for different sections.
The logic uses two dictionaries populated from an xml file. Because the file has mutliple tables, I combined them in the two dictionaries like so:
var headerCdataIndexKeyVals = Dictionary<string, int>(){
{"data.tool_context.TOOL_SOFTWARE_VERSION", 1},
{"data.context.TOOL_ENTITY",0}
};
var headerCdataArrayKeyVals = new Dictionary<string, List<string>>();
var tool_contextCdataList = new list <string>{"HM654", "sw0.2.002"};
var contextCdataList = new List<string>{"WSM102"}
headerCdataArrayKeyVals.add("tool_context", tool_contextCdataList);
headerCdataArrayKeyVals.add("context", contextCdataList);
To help me map the values to their respective positions in the string in one go and without having to loop through multiple dictionaries.
I am using the following logic:
public static string FindSubsInDelimetersAndReturn(string str, char openDelimiter, char closeDelimiter, HeaderMapperData mapperData )
{
string newString = string.Empty;
// Stores the indices of
Stack <int> dels = new Stack <int>();
for (int i = 0; i < str.Length; i++)
{
var let = str[i];
// If opening delimeter
// is encountered
if (str[i] == openDelimiter && dels.Count == 0)
{
dels.Push(i);
}
// If closing delimeter
// is encountered
else if (str[i] == closeDelimiter && dels.Count > 0)
{
// Extract the position
// of opening delimeter
int pos = dels.Peek();
dels.Pop();
// Length of substring
int len = i - 1 - pos;
// Extract the substring
string headerSubstring = str.Substring(pos + 1, len);
bool hasKey = mapperData.HeaderCdataIndexKeyVals.TryGetValue(headerSubstring.ToUpper(), out int headerCdataIndex);
string[] headerSubstringSplit = headerSubstring.Split('.');
string headerCDataVal = string.Empty;
if (hasKey)
{
if (headerSubstring.Contains("CONTAINER.CONTEXT", StringComparison.OrdinalIgnoreCase))
{
headerCDataVal = mapperData.HeaderCdataArrayKeyVals[headerSubstringSplit[1].ToUpper() + '.' + headerSubstringSplit[2].ToUpper()][headerCdataIndex];
//mapperData.HeaderCdataArrayKeyVals[]
}
else
{
headerCDataVal = mapperData.HeaderCdataArrayKeyVals[headerSubstringSplit[1].ToUpper()][headerCdataIndex];
}
string strToReplace = openDelimiter + headerSubstring + closeDelimiter;
string sub = str.Remove(i + 1);
sub = sub.Replace(strToReplace, headerCDataVal);
newString += sub;
}
else if (headerSubstring == "WSM" && closeDelimiter == '#')
{
string sub = str.Remove(len + 1);
newString += sub.Replace(openDelimiter + headerSubstring + closeDelimiter, "");
}
else
{
newString += let;
}
}
}
return newString;
}
}
But my output turns out to be:
"\tFie\tField InspectionStationID 3 {\"PVA TePla#WSM#\", \"sw0.2.002\tField InspectionStationID 3 {\"PVA TePla#WSM#\", \"sw#data.tool_context.TOOL_SOFTWARE_VERSION#\", \"WSM102"
Can someone help understand why this is happening and how I can go about correcting it so I get the output:
Field InspectionStationID 3 {"PVA TePla", "sw0.2.002", "WSM102"}
Am i even trying to solve this the right way or is there a better cleaner way to do it? Btw if the key is not in the dictionary I replace it with empty string

Replace string if starts with string in List

I have a string that looks like this
s = "<Hello it´s me, <Hi how are you <hay"
and a List
List<string> ValidList= {Hello, hay} I need the result string to be like
string result = "<Hello it´s me, ?Hi how are you <hay"
So the result string will if it starts with an < and the rest bellogs to the list, keep it, otherwise if starts with < but doesn´t bellong to list replaces the H by ?
I tried using the IndexOf to find the position of the < and the if the string after starsWith any of the strings in the List leave it.
foreach (var vl in ValidList)
{
int nextLt = 0;
while ((nextLt = strAux.IndexOf('<', nextLt)) != -1)
{
//is element, leave it
if (!(strAux.Substring(nextLt + 1).StartsWith(vl)))
{
//its not, replace
strAux = string.Format(#"{0}?{1}", strAux.Substring(0, nextLt), strAux.Substring(nextLt + 1, strAux.Length - (nextLt + 1)));
}
nextLt++;
}
}
To give the solution I gave as a comment its proper answer:
Regex.Replace(s, string.Format("<(?!{0})", string.Join("|", ValidList)), "?")
This (obviously) uses regular expressions to replace the unwanted < characters by ?. In order to recognize those characters, we use a negative lookahead expression. For the example word list, this would look like this: (?!Hallo|hay). This will essentially match only if what we are matching is not followed by Hallo or hay. In this case, we are matching < so the full expression becomes <(?!Hallo|hay).
Now we just need to account for the dynamic ValidList by creating the regular expression on the fly. We use string.Format and string.Join there.
Something like this without using RegEx or LINQ
string s = "<Hello it´s me, <Hi how are you <hay";
List<string> ValidList = new List<string>() { "Hello", "hay" };
var arr = s.Split(new[] { '<' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < arr.Length; i++)
{
bool flag = false;
foreach (var item in ValidList)
{
if (arr[i].Contains(item))
{
flag = false;
break;
}
else
{
flag = (flag) ? flag : !flag;
}
}
if (flag)
arr[i] = "?" + arr[i];
else
arr[i] = "<" + arr[i];
}
Console.WriteLine(string.Concat(arr));
A possible solution using LINQ.It splits the string using < and checks if the "word" (text until a blank space found) following is in the Valid List,adding < or ? accordingly. Finally,it joins it all:
List<string> ValidList = new List<string>{ "Hello", "hay" };
string str = "<Hello it´s me, <Hi how are you <hay";
var res = String.Join("",str.Split(new char[] { '<' }, StringSplitOptions.RemoveEmptyEntries)
.Select(x => ValidList.Contains(x.Split(' ').First()) ? "<" + x : "?"+x));

How to add characters to a string in C#

Problem: I would like add characters to a phone.
So instead of displaying ###-###-####, I would like to display (###) ###-####.
I tried the following:
string x = "Phone_Number";
string y = x.Remove(0,2);//removes the "1-"
From here, I am not sure how I would add "()" around ###
Any help would be appreciated.
It's worth noting that strings are immutable in C#.. meaning that if you attempt to modify one you'll always be given a new string object.
One route would be to convert to a number (as a sanity check) then format the string
var result = String.Format("{0:(###) ###-####}", double.Parse("8005551234"))
If you'd rather not do the double-conversion then you could do something like this:
var result = String.Format("({0}) {1}-{2}", x.Substring(0 , 3), x.Substring(3, 3), x.Substring(6));
Or, if you already have the hyphen in place and really just want to jam in the parenthesis then you can do something like this:
var result = x.Insert(3, ")").Insert(0, "(");
To insert string in particular position you can use Insert function.
Here is an example:
string phone = "111-222-8765";
phone = phone.Insert(0, "("); // (111-222-8765
phone = phone.Insert(3, ")"); // (111)-222-8765
You can use a regular expression to extract the digit groups (regardless of - or () and then output in your desired format:
var digitGroups = Regex.Matches(x, #"(\d{3})-?(\d{3})-?(\d{4})")[0].Groups.Cast<Group>().Skip(1).Select(g => g.Value).ToArray();
var ans = $"({digitGroups[0]}) {digitGroups[1]}-{digitGroups[2]}";
I would do something like this:
string FormatPhoneNumber(string phoneNumber)
{
if (string.IsNullOrEmpty(phoneNumber))
throw new ArgumentNullException(nameof(phoneNumber));
var phoneParts = phoneNumber.Split('-');
if (phoneParts.Length < 3)
throw new ArgumentException("Something wrong with the input number format", nameof(phoneNumber));
var firstChar = phoneParts[0].First();
var lastChar = phoneParts[0].Last();
if (firstChar == '(' && lastChar == ')')
return phoneNumber;
else if (firstChar == '(')
return $"{phoneParts[0]})-{phoneParts[1]}-{phoneParts[2]}";
else if (lastChar == ')')
return $"({phoneParts[0]}-{phoneParts[1]}-{phoneParts[2]}";
return $"({phoneParts[0]})-{phoneParts[1]}-{phoneParts[2]}";
}
You would use it like this:
string n = "123-123-1234";
var formattedPhoneNumber = FormatPhoneNumber(n);

String concatenation based on best practices

I have a string,
string ij = "/alwaysSame09102012/myThing.aspx?asdasd=99&Urasdl=scashdasdeasdmeasds/tasdigaesdr1/gasdoasdveasdasdrnaasdancasde/eamsdeasdetiasdasdnagsds/tasidgeasdr1masdeetasdasd11180,/reasdMeasdetMe2as0d1asd0/asrdganasdiseasdasdgeasdetasdiasdngaasdsd.aasdspafsxasdffas?asdsdlaieasdnedtfe=asdsafaser1meafswedfhfdget111ertert80"
Now i just need to change the first "alwaysSame09102012" with "always2013forever".
I know i can do something like this,
string ij = "/alwaysSame09102012/myThing.aspx?asdasd=99&Urasdl=scashdasdeasdmeasds/tasdigaesdr1/gasdoasdveasdasdrnaasdancasde/eamsdeasdetiasdasdnagsds/tasidgeasdr1masdeetasdasd11180,/reasdMeasdetMe2as0d1asd0/asrdganasdiseasdasdgeasdetasdiasdngaasdsd.aasdspafsxasdffas?asdsdlaieasdnedtfe=asdsafaser1meafswedfhfdget111ertert80"
string[] c = ij.split['/'];
string finalString = ij.replace( "/" + c[0] + "/", "/" + "always2013forever" + "/");
This is my logic but no working, please help,
only constant in my string is "/alwaysSame09102012/" which i need to replace
Update
**
What if I got this "alwaysSame09102012" in at of my query string,
that's why I don't want to use replace.
**
Use String.Replace.
Ex:
var goodStr = ij.Replace("alwaysSame09102012", "always2013forever");
The reason your answer does not work is because c[0] is going to be "". The value you are looking for (e.g. 'alwaysSame09102012') is going to be in c[1].
string ij = "/alwaysSame09102012/myThing.aspx?asdasd=99&Urasdl=scashdasdeasdmeasds/tasdigaesdr1/gasdoasdveasdasdrnaasdancasde/eamsdeasdetiasdasdnagsds/tasidgeasdr1masdeetasdasd11180,/reasdMeasdetMe2as0d1asd0/asrdganasdiseasdasdgeasdetasdiasdngaasdsd.aasdspafsxasdffas?asdsdlaieasdnedtfe=asdsafaser1meafswedfhfdget111ertert80"
string newString = ij.Replace("alwaysSame09102012","always2013forever");
string ReplaceFirst (string source, string old_substring, string new_substring)
{
var position = source.IndexOf(old_substring);
return (position < 0)
? source
: source.Substring(0, position) + new_substring + source.Substring(position + old_substring.Length);
}
Usage:
var new_string = ReplaceFirst("/alwaysSame09102012/myThing...", "alwaysSame09102012","always2013forever");
You should use the URI classes.
http://msdn.microsoft.com/en-us/library/system.uri.aspx
http://msdn.microsoft.com/en-us/library/system.uribuilder.aspx
This will give you more flexibility, and prevent you from escaping problems etc.

How to split for only one string without using arrays

I've a string 01-India. I want to split on '-' and get only the code 01. How can I do this. I'm a .net newbie. Split function returns a array. Since I need only one string, how can this be done. Is there a ingenious way to do it using split only. Or do I've to use substring only?
Other possibility is
string xy = "01-India";
string xz = xy.Split('-')[0];
You can search for the first occurence of - and then use the method substring to cut the piece out.
var result = input.Substring(0, input.IndexOf('-'))
string str = "01-India";
string prefix = null;
int pos = str.IndexOf('-');
if (pos != -1)
prefix = str.SubString(0,pos);
var str = "01-India";
var hyphenIndex = str.IndexOf("-");
var start = str.substring(0, hyphenIndex);
or you can use regular expression if it is a more complicated string pattern.
Something like this?
var s = "01-India";
var result = s.SubString(0, s.IndexOf("-"));
Since you don't want to use arrays, you could do an IndexOf('-') and then a substring.
string s = "01-India"
int index = s.IndexOf('-');
string code = s.Substring(0, index);
Or, for added fun, you could use String.Remove.
string s = "01-India"
int index = s.IndexOf('-');
string code = s.Remove(index);
string value = "01-India";
string part1 = value.Split('-')[0];

Categories