正则表达式:判断字符串是否不包含特定字符

35

这次问题比较简单。

我正在尝试使用正则表达式测试一个字符串是否不包含某个字符。我认为表达式应该是形如"[^x]"的,其中x表示你不想出现的字符,但似乎并不起作用。

例如,

Regex.IsMatch("103","[^0]")

Regex.IsMatch("103&","[^&]")

两个都返回 true(我本来期望是 false)。

我开始使用 ""[^&]"",并认为可能需要将 & 转义为 \&,但似乎并没有什么区别。

有什么想法吗?我猜这是一个小问题。

另外,我正在使用 .NET,请注意这一点。

编辑1:

我找到了此内容,但似乎并没有解决我遇到的问题。

编辑2:

我想回应KevinJoel的建议。这些建议确实会更快,但它们无法满足我在这种情况下所需的灵活性,因此如果您通过搜索找到了这个问题,请确保查看他们的答案是否适合您的需求。在我的情况下,正则表达式被传递到一个 DataTable 验证方法中,该方法循环遍历每一行并验证该行特定列中的内容是否与传递进来的 RegEx 匹配。由于我将重复使用这个方法来验证其他几个被验证的 DataTable,所以我希望:

  1. 使用 Regex 来启用最广泛的验证,并且
  2. 始终寻找正向匹配(即不是使用 !Regex.IsMatch(cell, regexvariable) 的方式,而是依赖于始终能够使用 Regex.IsMatch(cell, regexvariable),因为调用此方法的大多数 DataTable 都将使用正向匹配,而不是负向匹配)。

希望这有所帮助。


如果你只是想检查单个字符是否存在,那么不使用正则表达式会更好。Kevin是正确的:使用.IndexOf()或其他更简单的方法。这样会更易读、更清晰、更快速。 - david
6个回答

53

你的解决方案有一半是正确的。您看到的匹配是针对其他字符的。您想要表达的是类似于“嘿!我不想在整个字符串中看到这个字符”。

在这种情况下,您可以采取以下步骤:

Regex.IsMatch("103","^[^0]*$")

谢谢!我之前也尝试过“^[^0]$”,但是放弃了使用 ^ 和 $,因为它会导致所有的东西都被判定为 false -- 只需要那个星号就好了。再次感谢 -- 我的“两个问题”现在已经解决了。 - jerhinesmith
4
我猜 !Regex.IsMatch("103","0") 会更快一些。 - Kip
我正在使用这个,我不想看到字符 ?[],我尝试了 ^[^?]*$,它对于 ? 基于以上的例子可以运行,但是当我加入方括号时却无法运作... ^[^?[]]*$ - raffian
1
@SAFX 当在字符集分隔符中使用 [] 这些字符时,你需要对它们进行转义。因此,你的最终正则表达式应为: ^[^\[\]]*$。希望能有所帮助。 - Neel

17

[^0]模式将匹配任何非零字符。 在您的两个示例中,该模式将匹配第一个字符(“1”)。 要测试整个字符串是否不包含零,请使用模式“^[^0]*$”。 它的含义如下:从字符串的开头开始,匹配任意数量的非零字符,紧接着是字符串的结尾。 任何包含零的字符串都将失败。 任何不包含零的字符串都将通过。


7
如果您想在字符串中查找单个字符,使用正则表达式似乎有点过头了。为什么不使用.IndexOf或.Contains?

这个方法可以实现,但我正在尝试使用装饰器编写一个 DataTable 验证器,并且我想要一个方法,使我能够扩展到其他字符串匹配(包括或排除)。 - jerhinesmith

4
解析器遇到的第一个字符是“1”,这对于[^0]和[^&]都是真的,因此在这两个示例中它将返回true。

2

我在寻找JavaScript时遇到了同样的问题。上面的表达式在我的情况下不起作用,但我发现下面的表达式可以。(以防其他寻找JavaScript解决方案的人也会来到这里。)

^((?!0).)*$

这个结构叫做“负向先行断言”,详细信息请参考这里


2

您将否定放在了错误的位置。 [^x] 将匹配任何不是 x 的字符。如果字符串中有 x,则只要还有其他字符,字符串仍与表达式匹配。相反,您想要匹配 x 存在时为 true,然后否定函数的结果:

Not Regex.IsMatch("103", "0")

Not Regex.IsMatch("103&", "&")

这些简单的示例并不意味着使用普通的String.IndexOf()或String.Contains()更好。


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