C# 过滤字符串

C# 过滤字符串,c#,string,filtering,C#,String,Filtering,我要确保字符串仅包含此范围内的字符 [a-z]&&&[a-z]&&&[0-9]&&&[-] 所有字母和数字加上连字符。 我试过这个 C#应用程序: char[]filteredChars={'、'、'!'、'@'、'#'、'$'、'%'、'^'、'&'、'*'、'('、')'、''''+'、'='、'{'、'}'、'['、'.'、':'、';'、''、''''''.'、''''.'、'.'、'.'、'.''''''''.'''''.'、'.'''''.''.''''.'''''''.'.'.''

我要确保字符串仅包含此范围内的字符

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

所有字母和数字加上连字符。 我试过这个

C#应用程序:

char[]filteredChars={'、'、'!'、'@'、'#'、'$'、'%'、'^'、'&'、'*'、'('、')'、''''+'、'='、'{'、'}'、'['、'.'、':'、';'、''、''''''.'、''''.'、'.'、'.'、'.''''''''.'''''.'、'.'''''.''.''''.'''''''.'.'.'''''''.''';
字符串s=str.TrimStart(filteredChars);
此TrimStart()似乎只适用于字母,而不适用于$%等Other字符

我实施错了吗? 有更好的方法吗

我只是想避免循环检查每个字符串的索引,因为将有很多字符串要做

想法


谢谢!

为什么不改用替换?Trimstart只会删除列表中的前导字符…

这似乎是使用替换的一个非常有效的理由

对于miguel的评论,您可以这样做来删除所有不需要的字符:

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

请注意,插入符号(
^
)现在被放置在character类中,因此会将其取反(匹配任何不允许的字符)。

我相信,再过一点时间,您可以找到更好的方法,但这会给您一个好主意:

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(" ", "");
}
公共字符串编号仅限字母(字符串s)
{
字符串rtn=s;
对于(int i=0;i
尝试以下操作

public bool isStringValid(string input) {
  if ( null == input ) { 
    throw new ArgumentNullException("input");
  }
  return System.Text.RegularExpressions.Regex.IsMatch(input, "^[A-Za-z0-9\-]*$");
}

这里有一个使用LINQ的有趣方法-没有丑陋的循环,没有复杂的正则表达式:

private string GetGoodString(string input)
{
   var allowedChars = 
      Enumerable.Range('0', 10).Concat(
      Enumerable.Range('A', 26)).Concat(
      Enumerable.Range('a', 26)).Concat(
      Enumerable.Range('-', 1));

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

喂它“喂,世界?123!它将返回“Helloworld123”“

我已经在Linqpad 5中测试了这两种解决方案。这样做的好处是,它们不仅可以用于整数,还可以用于带数字小数分隔符的小数/浮点,这取决于区域性。例如,在挪威,我们使用逗号作为十进制分隔符,而在美国,使用点。逗号用作千位分隔符。无论如何,首先是Linq版本,然后是正则表达式版本。最简洁的一点是访问数字分隔符的线程静态属性,但您可以在代码顶部使用static将其压缩一点,或者更好—将此类功能放入C#扩展方法中,最好使用带有任意正则表达式模式的重载

string crappyNumber = @"40430dfkZZZdfldslkggh430FDFLDEFllll340-DIALNOWFORCHRISTSAKE.,CAKE-FORFIRSTDIAL920932903209032093294faøj##R#KKL##K";

string.Join("", crappyNumber.Where(c => char.IsDigit(c)|| c.ToString() == Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)).Dump();

new String(crappyNumber.Where(c => new Regex($"[\\d]+{Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator}\\d+").IsMatch(c.ToString())).ToArray()).Dump();
注意上面的代码,Dump()方法将结果转储到Linqpad。您的代码当然会跳过最后一部分。还要注意的是,我们将其简化为一行程序,但仍然有点冗长,可以按照建议将其放入C#扩展方法中

此外,与string.join不同,新建一个新字符串对象的语法更紧凑,更不容易出错


我们得到了一个糟糕的数字作为输入,但我们最终还是得到了我们的数字!而且在C#中它具有文化意识

您应该检查输入是否有效,而不是它不应该接受的内容。使用正则表达式检查字符串。有一点免责声明:我只是从头开始做了这个模式,所以它可能不是你想要的。如果遵循链接,您将能够找到构建理想模式所需的信息。您需要在字符串前面放置一个@符号,这样它就不会试图转义-:Regex.Replace(s,@“[^A-z0-9 \-]”,“”);太棒了,正是我想要的!最重要的是什么?在表达式中执行?引用regular-expressions.info/reference.html:?“使前面的项成为可选项。贪婪,因此如果可能,可选项将包含在匹配项中。”现在我想,您可能不希望在这种特定模式中出现这种情况,但我认为它可以使用或不使用…只需编写一个循环来扫描并删除。哦,我只是注意到他不需要循环。此外,regex解决方案看起来更好。不过我不会删除我的帖子,因为其中一些方法可能仍然有用,或者您可以这样做:返回Regex.Replace(输入??string.Empty,@“[^A-z0-9 \-]”,“”);我必须说我喜欢这个,因为你在避免正则表达式=)+1!
private string GetGoodString(string input)
{
   var allowedChars = 
      Enumerable.Range('0', 10).Concat(
      Enumerable.Range('A', 26)).Concat(
      Enumerable.Range('a', 26)).Concat(
      Enumerable.Range('-', 1));

   var goodChars = input.Where(c => allowedChars.Contains(c));
   return new string(goodChars.ToArray());
}
string crappyNumber = @"40430dfkZZZdfldslkggh430FDFLDEFllll340-DIALNOWFORCHRISTSAKE.,CAKE-FORFIRSTDIAL920932903209032093294faøj##R#KKL##K";

string.Join("", crappyNumber.Where(c => char.IsDigit(c)|| c.ToString() == Thread.CurrentThread.CurrentCulture.NumberFormat.NumberDecimalSeparator)).Dump();

new String(crappyNumber.Where(c => new Regex($"[\\d]+{Thread.CurrentThread.CurrentUICulture.NumberFormat.NumberDecimalSeparator}\\d+").IsMatch(c.ToString())).ToArray()).Dump();