[\s\S]* 有啥区别?和 。*?在 Java 正则表达式中?

Posted

技术标签:

【中文标题】[\\s\\S]* 有啥区别?和 。*?在 Java 正则表达式中?【英文标题】:Whats the difference between [\s\S]*? and .*? in Java regular expressions?[\s\S]* 有什么区别?和 。*?在 Java 正则表达式中? 【发布时间】:2016-05-16 21:21:15 【问题描述】:

我开发了一个正则表达式来识别文本文件中的一个 xml 块。表达式看起来像这样(我已删除所有 java 转义斜杠以使其易于阅读):

<\?xml\s+version="[\d\.]+"\s*\?>\s*<\s*rdf:RDF[^>]*>[\s\S]*?<\s*\/\s*rdf:RDF\s*>

然后我对其进行了优化并将[\s\S]*?替换为.*?它突然停止识别xml。

据我所知,\s 表示所有空白符号,\S 表示所有非空白符号或[^\s] 所以[\s\S] 在逻辑上应该等同于. 我没有使用贪心过滤器,那有什么区别呢?

【问题讨论】:

默认情况下. 不匹配行分隔符。如果您使用Patter.DOTALL 标志,它可能匹配所有字符(包括行分隔符)。 [\s\S] 设置为包括所有空格 \s 和所有非空格 \S,有效地表示所有字符(包括行分隔符)。 尾随 ?在这两种情况下都没有任何贡献。 一个非常相关的:What's the difference between these RegEx 好问题,我真的很惊讶它没有更多的赞成票。 【参考方案1】:

Here 是一张解释所有正则表达式命令的表格。

基本上,\s\S 会拾取所有字符,包括换行符。而. 默认不拾取线路终止符(需要设置某些标志才能拾取它们)。

【讨论】:

是的,每个 \ 都被双重转义。为了便于阅读,我删除了双斜杠。该表达式有效,但一旦我将 [\s\S]*? 替换为 .*? 就会停止工作,因此应该存在差异。 这是真实的表达方式:&lt;\\?xml\\s+version=\"[\\d\\.]+\"\\s*\\?&gt;\\s*&lt;\\s*rdf:RDF[^&gt;]*&gt;[\\s\\S]*?&lt;\\s*\\/\\s*rdf:RDF\\s*&gt; 这不是真的。 . 可能会转义新行,具体取决于某些标志。请查看我的答案以了解所有详细信息.. @Neuron 我引用的消息来源指出. 不会捕获换行符。这就是我要离开的。我现在意识到它可能不像我想象的那么可信。【参考方案2】:

正则表达式 .\s\S 不等价,因为默认情况下 . 不会捕获行终止符(如换行符)。

根据oracle website,.匹配

任何字符(可能匹配也可能不匹配行终止符)

而行终止符是以下任何一种:

换行(换行)字符 ('\n'), 回车符后跟换行符 ("\r\n"), 独立的回车符 ('\r'), 下一行字符 ('\u0085'), 行分隔符 ('\u2028'),或 段落分隔符 ('\u2029)。

只要没有设置必要的标志,这两个表达式是不等价的。再次引用oracle网站:

如果UNIX_LINES 模式被激活,那么唯一的行终止符 识别为换行符。

正则表达式. 匹配除一行以外的任何字符 除非指定了 DOTALL 标志,否则终止符。

【讨论】:

以上是关于[\s\S]* 有啥区别?和 。*?在 Java 正则表达式中?的主要内容,如果未能解决你的问题,请参考以下文章

将字符串与指向字符串的指针作为参数传递给函数时,时间复杂度有啥区别?

VBS和JAVA和C++,有啥区别,有啥差距

java中接口和类有啥区别java中接口和类有啥区别

java中的interface和@interface有啥区别?

javaEE和java有啥区别

Java中的同步方法和同步块有啥区别? [复制]