【问题标题】: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,有效地表示所有字符(包括行分隔符)。
  • 尾随 ?在这两种情况下都没有任何贡献。
  • 好问题,我真的很惊讶它没有更多的赞成票。

标签: java regex xml


【解决方案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 标志,否则终止符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-05
    • 1970-01-01
    • 2014-09-26
    • 2013-03-15
    • 1970-01-01
    相关资源
    最近更新 更多