正则表达式[^\d\s]和[\D\S]之间有什么区别?

3
有人能解释一下[^\d\s][\D\S]之间的区别吗?来自http://www.regular-expressions.info/shorthand.html的描述并不是很清楚:
在使用方括号内的否定简写时要小心。 [\D\S][^\d\s]不同。后者匹配既不是数字也不是空格的任何字符。它会匹配x,但不会匹配8。然而,前者匹配任何不是数字或不是空格的字符。因为所有数字都不是空格,而所有空格字符都不是数字,所以[\D\S]匹配任何字符; 数字、空格或其他字符。
对我来说,它们似乎都一样。难道我错过了什么吗?

1
请阅读Oracle官方Java教程中的课程:正则表达式,并在此处找到完整的Java Regex Pattern列表及其详细描述。 - Braj
有没有一个答案解决了你的问题?我注意到你还没有在StackOverflow上投票。如果一个答案解决了你的问题,请考虑通过点击左侧的复选框“接受它”来接受它,因为这是声望系统的工作方式(接受一个答案会给回答者和你带来声望)。当然,没有义务这样做。稍后当你有更多的声望时,你也可以赞同问题。感谢您听我的20秒SO声望教程。 :) - zx81
2个回答

9
[^\d\s]

将匹配一个不是数字或空白字符的单个字符。

[\D\S]

该正则表达式将匹配一个非数字且非空白字符。

由于每个字符都不是数字或空格,第二个正则表达式将匹配任何字符。

这类似于以下两种方式的区别:

if (!(isdigit(c) || isspace(c))) ...

并且

if (!isdigit(c) || !isspace(c)) ...

请注意,以下内容与第一个内容等价(根据德摩根定律)。
if (!isdigit(c) && !isspace(c)) ...

感谢您的回答。 - user3694243

6
ooga的答案是正确的,但我发现你还没有完全理解。有时候用不同的措辞来解释是很有用的,让我试试。对我来说,误解真的很简单。Jan Goyvaerts(你所阅读网站的作者)并没有描述一个特定的正则表达式功能,只是字符类逻辑的一个结果。让我们从头开始:
1.一个字符类,比如[abc],表示“匹配一个字符,它是a或b或c之一。请注意,它不表示“匹配一个字符,它是a和b和c”,那样没有任何意义。
2.一个否定的字符类,比如[^abc],表示“匹配一个既不是a也不是b也不是c的字符,换句话说,它既不是a也不是b也不是c。注意,第1点都是关于“或”的,而第2点都是关于“和”的。
3.因此,[^\d\s]表示“匹配一个既不是数字也不是空格的字符”,而[\D\S]表示“匹配一个非数字或非空格的字符”。
你可以看到3和4是完全不同的。
什么意思呢?
我们允许“匹配一个既不是数字也不是空格的字符”。非数字可以是制表符等。好的,所以我们可以匹配一个制表符字符,并且\D实际上允许我们匹配任何空格,因为空格(例如制表符)永远不是数字。现在让我们看看\S。非空格可以表示9字符,所以\S允许我们匹配任何数字(和更多字符)。因为[\D\S]的意思是“一个字符,它要么是\D要么是\S”,但并不意味着“一个字符既是\D也是\S”,所以我们允许匹配任何数字和任何空格(实际上任何字符)。
与运算和或运算
关键在于数字1和4的字符类都表明“匹配一个字符,它是这些字符中的任意一个”。其中任意一个类似于使用OR。而在数字3中,我们使用既不。它类似于使用NOT关键字并将x和y排除在外。

1
@ooga 谢谢伙计,你的也很棒。 :) - zx81
1
我喜欢使用“C”语法进行解释。太棒了,任何对你有用的都可以 :) - zx81
我必须说,我一开始很难理解这个问题,但是你解释得非常清楚。如果我是提问者,我会把你的答案标记为最佳答案。非常感谢你的解答,我相信很多人都会从中受益。 - mishsx

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