views:

194

answers:

5
+2  Q: 

Filter a String

I want to make sure a string has only characters in this range

[a-z] && [A-Z] && [0-9] && [-]

so all letters and numbers plus the hyphen. I tried this...

C# App:

        char[] filteredChars = { ',', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '=', '{', '}', '[', ']', ':', ';', '"', '\'', '?', '/', '.', '<', '>', '\\', '|' };
        string s = str.TrimStart(filteredChars);

This TrimStart() only seems to work with letters no otehr characters like $ % etc

Did I implement it wrong? Is there a better way to do it?

I just want to avoid looping through each string's index checking because there will be a lot of strings to do...

Thoughts?

Thanks!

A: 

Why not just use replace instead? Trimstart will only remove the leading characters in your list...

miguel
Because then Ill have to have a tons of replace statements...
gmcalab
just write a loop to scan and remove then
miguel
+10  A: 

This seems like a perfectly valid reason to use a regular expression.

bool stringIsValid = Regex.IsMatch(inputString, @"^[a-zA-Z0-9\-]*?$");

In response to miguel's comment, you could do this to remove all unwanted characters:

string cleanString = Regex.Replace(inputString, @"[^a-zA-Z0-9\-]", "");

Note that the caret (^) is now placed inside the character class, thus negating it (matching any non-allowed character).

Tomas Lycken
A little disclaimer: I just made the pattern up from the top of my head, so it might not be exactly what you're after. You'll be able to find the information you need to construct your ideal pattern if you follow the link.
Tomas Lycken
i think he wanted to remove any chars that were unwanted, however...
miguel
You need to put an @ symbol infront of the string so it doesn't try to escape the - : Regex.Replace(s, @"[^A-z0-9\-]", "");
Joel
Awesome exactly what I was looking for!
gmcalab
Thanks, Joel - updated!
Tomas Lycken
What is the ? doing in the expression??
Dabblernl
Quote from regular-expressions.info/reference.html: ? "Makes the preceding item optional. Greedy, so the optional item is included in the match if possible." Now that I think about it, you might not want that in this specific pattern, but I think it'll work with or without...
Tomas Lycken
It would be wise to pre-compile the regex into a private static variable.
Matthew Flaschen
It would. However, this was not intended as the final solution, but merely as a pointer in the right direction =)
Tomas Lycken
A: 

I'm sure that with a bit more time you can come up wiht something better, but this will give you a good idea:

public string NumberOrLetterOnly(string s)
{
    string rtn = s;
    for (int i = 0; i < s.Length; i++)
    {
        if (!char.IsLetterOrDigit(rtn[i]) && rtn[i] != '-')
        {
            rtn = rtn.Replace(rtn[i].ToString(), " ");
        }
    }
    return rtn.Replace(" ", "");
}
Joel
Oh, I just noticed that he didn't want loops. Besides the regex solution looks better anyway.I won't delete my post though, because some of those methods still might be helpful
Joel
+1  A: 

Try the following

public bool isStringValid(string input) {
  if ( null == input ) { 
    throw new ArgumentNullException("input");
  }
  return System.Text.RegularExpressions.Regex.IsMatch(input, "^[A-Za-z0-9\-]*$");
}
JaredPar
Or you could do this: return Regex.Replace(input ?? string.Empty, @"[^A-z0-9\-]", "");
Joel
+4  A: 

Here's a fun way to do it with LINQ - no ugly loops, no complicated RegEx:

private string GetGoodString(string input)
{
   var allowedChars = 
          Enumerable.Range('0', '9').Concat(
          Enumerable.Range('a', 'z')).Concat(
          Enumerable.Range('-', '-'));

   var goodCharsInInput = input.Where(c => allowedChars.Contains(c));
   return new string(goodCharsInInput.ToArray());
}

Feed it "Hello there, world123!" and it will return "Hellothereworld123".

Judah Himango
I must say I like this, just because you're avoiding RegExes =) +1!
Tomas Lycken