检查字符串是否只包含字母、数字和下划线。

12

我需要检查一个字符串是否只包含字母、数字和下划线。这是我的尝试,但它不起作用:

for(int i = 0; i<=snameA.Length-1; i++)
{
    validA = validA && (char.IsLetterOrDigit(snameA[i])||snameA[i].Equals("_"));
}

2
尝试使用正则表达式检查此模式:([A-Za-z0-9-_]+) - Red
我不知道。validA是一个布尔值,只有在满足条件的情况下才必须设置为true,但即使字符串包含特殊字符,它也会被设置为true。 - user3677169
“不起作用”包括什么?错误?无效结果? - Sayse
注意:代码已经被修改。 - Caramiriel
我添加了“validA &&”,但它仍然无法正常工作。 - user3677169
6个回答

14

我喜欢 Linq 因为它可以方便地回答这种问题:

bool validA = sname.All(c => Char.IsLetterOrDigit(c) || c.Equals('_'));

10

每次都给validA重新赋值,而没有检查它之前的值。现在你总是获取最后执行的检查结果。

你可以使用“and”操作符来处理结果:

validA &= (char.IsLetterOrDigit(snameA[i]) || snameA[i] == '_');
这意味着您仍然运行所有字符,但如果第一个检查失败,则可能是无用的。因此,最好在失败时直接跳出:
for(int i = 0; i<=snameA.Length-1; i++)
{
    validA = (char.IsLetterOrDigit(snameA[i]) || snameA[i] == '_');

    if (!validA)
    { break; } // <-- see here
}

或者使用 LINQ:

validA = snameA.All(c => char.IsLetterOrDigit(c) || c == '_');

1
我已经取消了我的反对票。使用正则表达式可能是个人选择的问题,而你的答案也完全正确。 - Dinos
谢谢。我并不是说 OP 不应该使用正则表达式,但现在他知道了自己代码的问题所在。 :) 感谢你的诚实。 - Patrick Hofman

5
你可以使用正则表达式。
Regex regex1 = new Regex(@"^[a-zA-Z0-9_]+$");

if(regex1.IsMatch(snameA))
{

}

Regex将自身实例作为参数! - Bharadwaj
顺便提一下,a-zA-Z0-9_\w 是一样的。 - Thomas Ayoub
3
@Thomas:不,存在微妙的区别:a-zA-Z0-9_ 仅接受 英文 字母,而 \w 接受 任何 字母,例如 Переменная(俄语中的变量)。你是完全正确的:问题中当前的实现(通过 char.IsLetterOrDigit)对应于正则表达式中的 \w* - Dmitry Bychenko

3
我会使用正则表达式。
string pattern = @"^[a-zA-Z0-9\_]+$";
Regex regex = new Regex(pattern);

// Compare a string against the regular expression
return regex.IsMatch(stringToTest);

3
您可以尝试匹配正则表达式。有一个内置类型用于“字母、数字和下划线”,即“\w”。
Regex rgx = new Regex(@"\w*");
rgs.IsMatch(yourString);

如果您需要一个或多个,请使用 "\w+"。
更多信息请参考:Regex.IsMatch

2
如果一个字符串仅包含字母、数字和下划线,则检查它。 => 请检查该字符串是否包含任何字母、数字和下划线。 - Thomas Ayoub

1

首先,“letter”这个词有点模糊:您是指a..z和A..Z字符,还是字母可以属于任何字母表,例如а..я和А..Я(俄语,西里尔字母)。根据您的当前实现,您想要第二个选项。

使用循环的典型解决方案是一直检查直到找到第一个反例:

  Boolean validA = true; // true - no counter examples so far

  // Why for? foreach is much readble here
  foreach(Char ch in sname) 
    // "!= '_'" is more readable than "Equals"; and wants no boxing
    if (!char.IsLetterOrDigit(ch) && ! (ch != '_')) { 
      Boolean validA = false; // counter example (i.e. non-letter/digit symbol found)

      break; // <- do not forget this: there's no use to check other characters
    }

然而,您可以使用Linq简化代码:

  validA = sname.All(ch => Char.IsLetterOrDigit(ch) || ch == '_');

或者正则表达式:
  validA = Regex.IsMatch(sname, @"^\w*$");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接