【问题标题】:Check string for invalid characters? Smartest way?检查字符串是否有无效字符?最聪明的方法?
【发布时间】:2012-09-03 06:24:53
【问题描述】:

我想检查一些字符串是否有无效字符。对于无效字符,我的意思是不应该存在的字符。这些是什么角色?这是不同的,但我认为那不是那么重要,重要的是我应该如何做到这一点,最简单和最好的方法(性能)是什么?

假设我只想要包含 'A-Z'、'empty'、'.'、'$'、'0-9' 的字符串

所以如果我有一个像“HELLO STaCKOVERFLOW”这样的字符串 => 无效,因为 'a'。 好的,现在该怎么做?我可以创建一个List<char> 并将每个不允许的字符放入其中,并使用此列表检查字符串。也许不是一个好主意,因为那时有很多字符。但是我可以制作一个包含所有允许字符的列表,对吗?然后?对于字符串中的每个字符,我必须比较 List<char>?有任何智能代码吗?还有一个问题:如果我将 A-Z 添加到 List<char> 我必须手动添加 25 个字符,但这些字符在 ASCII 表中是我知道的 65-90,我可以更轻松地添加它们吗?有什么建议?谢谢

【问题讨论】:

  • 您可以使用您对字符列表的想法,然后使用字符串的 indexof 来执行此操作,或者使用正则表达式。
  • 请在一个 SO 问题中只问一个问题。如果您有两个问题,请提出两个 SO 问题。谢谢。

标签: c# .net list char


【解决方案1】:

如果您对正则表达式不太擅长,那么在 C# 中还有另一种方法可以解决这个问题。这是我编写的用于测试名为 notifName 的字符串变量的代码块:

var alphabet = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z";
var numbers = "0,1,2,3,4,5,6,7,8,9";
var specialChars = " ,(,),_,[,],!,*,-,.,+,-";
var validChars = (alphabet + "," + alphabet.ToUpper() + "," + numbers + "," + specialChars).Split(',');
for (int i = 0; i < notifName.Length; i++)
{
    if (Array.IndexOf(validChars, notifName[i].ToString()) < 0) {
        errorFound = $"Invalid character '{notifName[i]}' found in notification name.";
        break;
        }
}

您可以根据需要更改添加到数组中的字符。 Array IndexOf 方法是整个事情的关键。当然,如果您希望逗号有效,则需要选择不同的拆分字符。

【讨论】:

    【解决方案2】:

    如果您使用的是 c#,您可以使用 List 和 contains 轻松完成此操作。你可以用单个字符(在一个字符串中)或一个多字符的字符串来做到这一点

      var pn = "The String To ChecK";      
      var badStrings = new List<string>()
      {
      " ","\t","\n","\r"
      };
      foreach(var badString in badStrings)
      {
        if(pn.Contains(badString))
        {
         //Do something
        }
      }
    

    【讨论】:

      【解决方案3】:

      我刚刚写了这样一个函数,以及一个扩展版本,在需要时限制第一个和最后一个字符。原始函数仅检查字符串是否仅包含有效字符,扩展函数在检查第一个和最后一个字符时将要跳过的列表开头的有效字符数添加两个整数,实际上它只是调用原始函数 3 次,在下面的示例中,它确保字符串以字母开头并且不以下划线结尾。

      StrChr(String, "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
      StrChrEx(String, "_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ", 11, 1));
      
      
      BOOL __cdecl StrChr(CHAR* str, CHAR* chars)
      {
       for (int s = 0; str[s] != 0; s++)
       {
           int c = 0;
      
          while (true)
          {
              if (chars[c] == 0)
              {
                   return false;
              }
               else if (str[s] == chars[c])
               {
                  break;
               }
              else
               {
                  c++;
               }
           }
       }
      
      return true;
      }
      
      BOOL __cdecl StrChrEx(CHAR* str, CHAR* chars, UINT excl_first, UINT excl_last)
      {
      char first[2]   = {str[0], 0};
      char last[2]    = {str[strlen(str) - 1], 0};
      
      if (!StrChr(str, chars))
      {
          return false;
      }
      
      if (excl_first != 0)
      {
          if (!StrChr(first, chars + excl_first))
          {
              return false;
          }
      }
      
      if (excl_last != 0)
      {
          if (!StrChr(last, chars + excl_last))
          {
              return false;
          }
      }
      
      return true;
      }
      

      【讨论】:

        【解决方案4】:

        您可以为此使用正则表达式:

        Regex r = new Regex("[^A-Z0-9.$ ]$");
        if (r.IsMatch(SomeString)) {
            // validation failed
        }
        

        要从A-Z0-9 创建一个字符列表,您可以使用一个简单的循环:

        for (char c = 'A'; c <= 'Z'; c++) {
            // c or c.ToString() depending on what you need
        }
        

        但您不需要使用 Regex - 几乎每个 regex 引擎都了解范围语法 (A-Z)。

        【讨论】:

        • 啊,这可能比比较列表要容易得多。好主意
        • 对此有一个问题。不应该有 if (!r.IsMatching(Something)) => 验证失败吗?因为如果它的匹配验证很好,或者?
        • 不,如果字符串包含[A-Z0-9.$ ] 范围内的任何 not 字符,则正则表达式匹配 - 这样效率更高,因为正则表达式引擎可以立即停止找到了这样一个角色。
        • 啊,我很困惑,因为从未在 C# 中使用过正则表达式。所以正则表达式开头的“^”类似于“!” (不)
        • 是的,它否定了字符类。
        猜你喜欢
        • 2020-01-19
        • 2017-03-29
        • 2013-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-15
        • 2019-05-05
        相关资源
        最近更新 更多