[\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]*?
替换为 .*?
就会停止工作,因此应该存在差异。
这是真实的表达方式:<\\?xml\\s+version=\"[\\d\\.]+\"\\s*\\?>\\s*<\\s*rdf:RDF[^>]*>[\\s\\S]*?<\\s*\\/\\s*rdf:RDF\\s*>
这不是真的。 .
可能会转义新行,具体取决于某些标志。请查看我的答案以了解所有详细信息..
@Neuron 我引用的消息来源指出.
不会捕获换行符。这就是我要离开的。我现在意识到它可能不像我想象的那么可信。【参考方案2】:
正则表达式 .
和 \s\S
不等价,因为默认情况下 .
不会捕获行终止符(如换行符)。
根据oracle website,.
匹配
任何字符(可能匹配也可能不匹配行终止符)
而行终止符是以下任何一种:
换行(换行)字符 ('\n'
), 回车符后跟换行符 ("\r\n"
), 独立的回车符 ('\r'
), 下一行字符 ('\u0085'
), 行分隔符 ('\u2028'
),或 段落分隔符 ('\u2029
)。
只要没有设置必要的标志,这两个表达式是不等价的。再次引用oracle网站:
如果
UNIX_LINES
模式被激活,那么唯一的行终止符 识别为换行符。正则表达式
.
匹配除一行以外的任何字符 除非指定了DOTALL
标志,否则终止符。
【讨论】:
以上是关于[\s\S]* 有啥区别?和 。*?在 Java 正则表达式中?的主要内容,如果未能解决你的问题,请参考以下文章
将字符串与指向字符串的指针作为参数传递给函数时,时间复杂度有啥区别?