Filtering comma separated String in C# - c#

I have a dynamic String value which may contain values like this
"Apple ,Banana, , , , Mango ,Strawberry , "
I would like to filter this string like
"Apple,Banana,Mango,Strawberry".
I have tried with the following code and it works.
Is there any better approach to achieve the same in C#(.NET 2.0)?
/// <summary>
/// Convert "Comma Separated String" to "Comma Separated String"
/// </summary>
/// <param name="strWithComma">String having values separated by comma</param>
/// <returns>String separated with comma</returns>
private String CommaSeparatedString(String strWithComma)
{
String rtn = String.Empty;
List<String> newList= new List<string>();
if (String.IsNullOrEmpty(strWithComma))
{
return rtn;
}
String[] strArray = strWithComma.Split(",".ToCharArray());
if (strArray == null || strArray.Length == 0)
{
return rtn;
}
String tmpStr = String.Empty;
String separator=String.Empty;
foreach (String s in strArray)
{
if (!String.IsNullOrEmpty(s))
{
tmpStr =s.Replace(Environment.NewLine, String.Empty);
tmpStr = tmpStr.Trim();
if (!String.IsNullOrEmpty(tmpStr))
{
newList.Add(tmpStr);
}
}
}
if (newList != null && newList.Count > 0)
{
rtn = String.Join(",", newList.ToArray());
}
return rtn;
}

you can also use Regex:
string str = #"Apple ,,Banana, , , , Mango ,Strawberry , ";
string result = Regex.Replace(str, #"(\s*,\s*)+", ",").TrimEnd(',');

I believe the following should do the trick on any .NET version:
string[] TrimAll( string[] input )
{
var result = new List<string>();
foreach( var s in input )
result.Add( s.Trim() );
}
return result.ToArray();
}
var delimiters = new [] { ",", "\t", Environment.NewLine };
string result = string.Join(",", TrimAll( input.Split( delimiters, StringSplitOptions.RemoveEmptyEntries ) ) );
Edit: updated to deal with white-space, tabs and newline.

Assuming that your items do not contain spaces:
private String CommaSeparatedString(String strWithComma)
{
string[] tokens = strWithComma
.Replace(" ", "")
.Split(new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
return string.Join(",", tokens);
}
Now I'm not sure if C# 2.0 accepts the new char[] {','} syntax. If not, you can define the array somewhere else (as a class private member, for example).

Here's a one-liner:
var outputString = string.Join(",", inputString.Replace(" ", string.Empty).Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));

Regex regex = new Regex(#"\w(?:(?!,| ).)*");
var items = regex.Matches("Apple ,Banana, , , , Mango ,Strawberry , ").Cast<Match>().Select(m => m.Value);
.NET 2.0 Version
List<string> newList = new List<string>();
Regex regex = new Regex(#"\w(?:(?!,| ).)*");
string str = "Apple ,Banana, , , , Mango ,Strawberry , ";
MatchCollection matches = regex.Matches(str);
foreach (Match match in matches)
{
newList.Add(match.Value);
}

var result = Regex.Replace(strWithComma, ",+", ",").TimEnd(',');
result = Regex.Replace(result, "\s+", string.Empty);

With no regular expressions, no splits and joins, trims, etc, O(n) time. StringBuilder is a very good class to work with strings.
EDIT
If the string it doesn't end with a letter it will add a comma. So an extra TrimEnd(',') is added
string strWithComma = ",Apple ,Banana, , , , Mango ,Strawberry , \n John,";
var sb = new StringBuilder();
var addComma = false;
foreach (var c in strWithComma )
{
if (Char.IsLetter(c)) // you might want to allow the dash also: example Anne-Marie
{
addComma = true;
sb.Append(c);
}
else
{
if (addComma)
{
addComma = false;
sb.Append(',');
}
}
}
string rtn = sb.ToString().TrimEnd(',');

Warning this method will only apply for C# 3.0 or higher. Sorry guys didnt read the question well enough
This will work but it can be done much easier like:
string input = "apple,banana,, \n,test\n, ,juice";
var parts = from part in input.Split(',')
let trimmedPart = part.Replace("\n", "")
where !string.IsNullOrWhiteSpace(trimmedPart)
select trimmedPart;
string result = string.Join(",", parts);

Related

Replacing commas in a string with brackets and commas if they don't exist

I am trying to manipulate and clean up a string of database columns as follows.
Example Source string(s):
[foo],[bar],baz
[foo],bar,[baz]
[foo],[bar,[baz]
[foo],bar],[baz]
foo,bar,baz
(and so on)
Expected output:
[foo],[bar],[baz]
I have tried to run the following regex substitutions over the string:
string columnString = "[foo],[bar],baz";
if (!Regex.IsMatch(columnString, #"^\[.*"))
{
columnString = string.Concat("[", columnString);}
if (!Regex.IsMatch(columnString, #"^.*\]$"))
{
columnString = string.Concat(columnString,"]");
}
while (!Regex.IsMatch(columnString, #"^.*\],.*$"))
{
columnString = Regex.Replace(columnString, #",", #"],");}
while (!Regex.IsMatch(columnString, #"^.*,\[.*$"))
{
columnString = Regex.Replace(columnString, #"\],", #"],[");
}
While this fixes up the leading and trailing brackets, it (obviously) doesn't deal with the commas where there is already an existing match in the string.
Can anyone suggest a method that would clean this up (it doesn't have to be regex).
Cheers
I suggest a splitting and string rebuilding solution:
var result = string.Join(
",",
s.Split(',') // split with commas
.Select(x => !x.StartsWith("[") && !x.EndsWith("]") ? $"[{x}]" : x ) // add [ ] to items not starting and ending with [ ]
);
See C# demo:
var strs = new List<string> { "[foo],[bar],baz", "[foo],bar,[baz]", "foo,bar,baz" };
foreach (var s in strs)
{
var result = string.Join(",", s.Split(',').Select(x => !x.StartsWith("[") && !x.EndsWith("]") ? $"[{x}]" : x ));
Console.WriteLine(result);
}
Output:
[foo],[bar],[baz]
[foo],[bar],[baz]
[foo],[bar],[baz]
Updated
As there may be items with either [ at the start or a ] at the end you may use
var result = string.Join(
",",
s.Split(',')
.Select(x => !x.StartsWith("[") || !x.EndsWith("]") ?
$"[{Regex.Replace(x, #"^\[|]$", "")}]" : x
)
);
See this C# demo. Result:
[foo],[bar],[baz],[test]
[foo],[bar],[baz],[test]
[foo],[bar],[baz]
Note that Regex.Replace(x, #"^\[|]$", "") removes a [ at the start and ] at the end of the string.
string str = "[foo],[bar],baz";
str = "[" + str.Replace("[", "").Replace("]", "").Replace(",", "],[") + "]";
Use StringBuilder if possible. I just gave you an idea using String class.
If you want to use regular expression, here is the answer:
var input = "[foo],bar,[baz]";
var regex = new Regex("((\\[?)((foo)|(bar)|(baz))(\\]?))");
var result = regex.Replace(input, "[$3]");
Please see: https://dotnetfiddle.net/Afnn3m

Check a pattern in a string then convert it to upper case

I was not clear with my previous question
I have a list: new List<string> { "lts", "mts", "cwts", "rotc" };
Now I wan't to check a pattern in string that starts or ends with a forward slash like this: "cTws/Rotc/lTs" or "SomethingcTws cWtS/Rotc rOtc".
and convert to upper case only the string that starts/ends with a forward slash based on the list that I have.
So the output should be: "CWTS/ROTC/LTS", "SomethingcTws CWTS/ROTC rOtc"
I modified Sachin's answer:
List<string> replacementValues = new List<string>
{
"cwts",
"mts",
"rotc",
"lts"
};
string pattern = string.Format(#"\G({0})/?", string.Join("|", replacementValues.Select(x => Regex.Escape(x))));
Regex regExp = new Regex(pattern, RegexOptions.IgnoreCase);
string value = "Cwts/Rotc Somethingcwts1 Cwts/Rotc/lTs";
string result = regExp.Replace(value, s => s.Value.ToUpper());
Result: CWTS/ROTC Somethingcwts1 Cwts/Rotc/lTs
The desired output should be: CWTS/ROTC Somethingcwts1 CWTS/ROTC/LTS
So instead of using Regex, which I'm not really good with, I'm doing split by space then split by "/" then rejoin the strings
string val = "Somethingrotc1 cWts/rOtC/lTs Cwts";
List<string> replacementValues = new List<string>
{
"lts", "mts",
"cwts", "rotc"
};
string[] tokens = val.Split(new char[] { ' ' }, StringSplitOptions.None);
string result = string.Join(" ", tokens.Select(t =>
{
// Now split by "/"
string[] ts = t.Split(new char[] { '/' }, StringSplitOptions.None);
if (ts.Length > 1)
{
t = string.Join("/", ts.Select(x => replacementValues.Contains(x.ToLower()) ? x.ToUpper() : x));
}
return t;
}));
Output: Somethingrotc1 CWTS/ROTC/LTS Cwts
You want to change the specific words in the string to Upper case. Then you can use Regex to achieve it.
string value = "Somethingg1 Cwts/Rotc/Lts Cwts";
var replacementValues = new Dictionary<string, string>()
{
{"Cwts","CWTS"},
{"Rotc","ROTC"},
{"Lts","LTC"}
};
var regExpression = new Regex(String.Join("|", replacementValues.Keys.Select(x => Regex.Escape(x))));
var outputString = regExpression.Replace(value, s => replacementValues[s.Value]);

How to remove " [ ] \ from string

I have a string
"[\"1,1\",\"2,2\"]"
and I want to turn this string onto this
1,1,2,2
I am using Replace function for that like
obj.str.Replace("[","").Replace("]","").Replace("\\","");
But it does not return the expected result.
Please help.
You haven't removed the double quotes. Use the following:
obj.str = obj.str.Replace("[","").Replace("]","").Replace("\\","").Replace("\"", "");
Here is an optimized approach in case the string or the list of exclude-characters is long:
public static class StringExtensions
{
public static String RemoveAll(this string input, params Char[] charactersToRemove)
{
if(string.IsNullOrEmpty(input) || (charactersToRemove==null || charactersToRemove.Length==0))
return input;
var exclude = new HashSet<Char>(charactersToRemove); // removes duplicates and has constant lookup time
var sb = new StringBuilder(input.Length);
foreach (Char c in input)
{
if (!exclude.Contains(c))
sb.Append(c);
}
return sb.ToString();
}
}
Use it in this way:
str = str.RemoveAll('"', '[', ']', '\\');
// or use a string as "remove-array":
string removeChars = "\"{[]\\";
str = str.RemoveAll(removeChars.ToCharArray());
You should do following:
obj.str = obj.str.Replace("[","").Replace("]","").Replace("\"","");
string.Replace method does not replace string content in place. This means that if you have
string test = "12345" and do
test.Replace("2", "1");
test string will still be "12345". Replace doesn't change string itself, but creates new string with replaced content. So you need to assign this new string to a new or same variable
changedTest = test.Replace("2", "1");
Now, changedTest will containt "11345".
Another note on your code is that you don't actually have \ character in your string. It's only displayed in order to escape quote character. If you want to know more about this, please read MSDN article on string literals.
how about
var exclusions = new HashSet<char>(new[] { '"', '[', ']', '\\' });
return new string(obj.str.Where(c => !exclusions.Contains(c)).ToArray());
To do it all in one sweep.
As Tim Schmelter writes, if you wanted to do it often, especially with large exclusion sets over long strings, you could make an extension like this.
public static string Strip(
this string source,
params char[] exclusions)
{
if (!exclusions.Any())
{
return source;
}
var mask = new HashSet<char>(exclusions);
var result = new StringBuilder(source.Length);
foreach (var c in source.Where(c => !mask.Contains(c)))
{
result.Append(c);
}
return result.ToString();
}
so you could do,
var result = "[\"1,1\",\"2,2\"]".Strip('"', '[', ']', '\\');
Capture the numbers only with this regular expression [0-9]+ and then concatenate the matches:
var input = "[\"1,1\",\"2,2\"]";
var regex = new Regex("[0-9]+");
var matches = regex.Matches(input).Cast<Match>().Select(m => m.Value);
var result = string.Join(",", matches);

Remove specific symbol from string

I have different string that starts and ends with { } like so {somestring}. I want to remove the delimiters from the string so that it shows somestring only. I can't do anything that counts the letters because I don't always know the length of the string.
Maybe this will help. Here is the code, somewhere here I want to delete the delimiters.
private static MvcHtmlString RenderDropDownList(FieldModel model)
{
ISerializer serializer = new SerializeJSon();
var value = "";
var tb1 = new TagBuilder("select");
tb1.MergeAttribute("id", model.QuestionId);
tb1.MergeAttribute("name", model.QuestionId);
tb1.MergeAttributes(GetHtmlAttributes(model.HtmlAttributes));
tb1.AddCssClass("form-field");
var sb = new StringBuilder();
MatchCollection matches = RegexHelper.GetBetweenDelimiter(model.FieldValues, "{", "}");
foreach (Match match in matches)
{
var o = match; //Solution var o = match.toString();
var tb2 = new TagBuilder("option");
//Solution string newString = o.trim(new [] { "{","}"});
tb2.SetInnerText(o.ToString()); //Solution tb2.SetInnerText(newString);
sb.Append(tb2.ToString(TagRenderMode.Normal) + "\n");
}
tb1.InnerHtml = sb.ToString();
return new MvcHtmlString(tb1.ToString(TagRenderMode.Normal));
}
string newString = originalString.Trim(new[] {'{', '}'});
Can you use Replace
string somestring = somestring.Replace("{","").Replace("}","");
Alternatively, you can use StartsWith and EndsWith which will only remove from the beginning and the end of the string, for example:
string foo = "{something}";
if (foo.StartsWith("{"))
{
foo = foo.Remove(0, 1);
}
if (foo.EndsWith("}"))
{
foo = foo.Remove(foo.Length-1, 1);
}
You could use replace e.g.
string someString = "{somestring}";
string someOtherString = someString.Replace("{","").Replace("}","");

Searching the first few characters of every word within a string in C#

I am new to programming languages. I have a requirement where I have to return a record based on a search string.
For example, take the following three records and a search string of "Cal":
University of California
Pascal Institute
California University
I've tried String.Contains, but all three are returned. If I use String.StartsWith, I get only record #3. My requirement is to return #1 and #3 in the result.
Thank you for your help.
If you're using .NET 3.5 or higher, I'd recommend using the LINQ extension methods. Check out String.Split and Enumerable.Any. Something like:
string myString = "University of California";
bool included = myString.Split(' ').Any(w => w.StartsWith("Cal"));
Split divides myString at the space characters and returns an array of strings. Any works on the array, returning true if any of the strings starts with "Cal".
If you don't want to or can't use Any, then you'll have to manually loop through the words.
string myString = "University of California";
bool included = false;
foreach (string word in myString.Split(' '))
{
if (word.StartsWith("Cal"))
{
included = true;
break;
}
}
I like this for simplicity:
if(str.StartsWith("Cal") || str.Contains(" Cal")){
//do something
}
You can try:
foreach(var str in stringInQuestion.Split(' '))
{
if(str.StartsWith("Cal"))
{
//do something
}
}
You can use Regular expressions to find the matches. Here is an example
//array of strings to check
String[] strs = {"University of California", "Pascal Institute", "California University"};
//create the regular expression to look for
Regex regex = new Regex(#"Cal\w*");
//create a list to hold the matches
List<String> myMatches = new List<String>();
//loop through the strings
foreach (String s in strs)
{ //check for a match
if (regex.Match(s).Success)
{ //add to the list
myMatches.Add(s);
}
}
//loop through the list and present the matches one at a time in a message box
foreach (String matchItem in myMatches)
{
MessageBox.Show(matchItem + " was a match");
}
string univOfCal = "University of California";
string pascalInst = "Pascal Institute";
string calUniv = "California University";
string[] arrayofStrings = new string[]
{
univOfCal, pascalInst, calUniv
};
string wordToMatch = "Cal";
foreach (string i in arrayofStrings)
{
if (i.Contains(wordToMatch)){
Console.Write(i + "\n");
}
}
Console.ReadLine();
}
var strings = new List<string> { "University of California", "Pascal Institute", "California University" };
var matches = strings.Where(s => s.Split(' ').Any(x => x.StartsWith("Cal")));
foreach (var match in matches)
{
Console.WriteLine(match);
}
Output:
University of California
California University
This is actually a good use case for regular expressions.
string[] words =
{
"University of California",
"Pascal Institute",
"California University"
}
var expr = #"\bcal";
var opts = RegexOptions.IgnoreCase;
var matches = words.Where(x =>
Regex.IsMatch(x, expr, opts)).ToArray();
The "\b" matches any word boundary (punctuation, space, etc...).

Categories

Resources