点符号(.)匹配几乎任何字符

在正则表达式中,点符号.是最常用的元字符,也是最被滥用的元字符。

点符号.匹配单个字符,不管是什么字符,为一的例外就是换行符。本教程中所涉及到的正则表达式,点符号.默认情况下不会匹配一个换行符,所以这点符号.其实就是[^\n](Unix环境下)或者[^\r\n] (Windows 环境下)的简写。

这个例外的存在最可能是由于历史原因。第一个正则表达式工具是基于行的,他们一行一行的读文件,每一行各自去匹配正则表达式。这个影响就是,使用这些工具,字符串中不会出现换行符,所以点符号.不会去匹配他们。现在的工具和语言可以让正则表达式作用于大字符串甚至整个文件。本教程中讨论的正则表达式都能设置成使之匹配包括换行符。 在RegexBuddy, EditPad Pro 或者 PowerGREP中,只需勾选中选项"dot matches newline"。

在Perl中,匹配换行符的模式称作单行模式。有点不幸的是,这很容易和术语“多行模式“搞混。多行模式只影响锚,单行模式只影响点符号(.)。你可通过在正则表达式后面加上一个s来激活单行模式,例如m/^regex$/s。

其他语言和正则表达式也采用了Perl的术语。当使用.NET的正则表达式库的时候,需要通过指定RegexOptions.Singleline激活单行模式。例如Regex.Match("string", "regex", RegexOptions.Singleline).

在我所知的程序语言和正则表达式库中,激活单行模式除了让点符号匹配换行符之外没有别的效用。

javascript和VBScript没有让点符号.匹配换行符的选项。着这些语言里,你可以使用字符集,比如 [\s\S] 来匹配任意字符。这个字符集匹配一个空白符包括换行符或者不是空白符,这就逻辑上等于匹配了任何字符。

 

保守的使用点符号点符号.

点符号.是一个强力的正则字符,让你变懒。但是点符号.也会让你匹配不该匹配的字符。如果你初学正则表达式,最初的一些情况你可能不是很清楚。

举例说明。比如要匹配日期mm/dd/yy,但是允许用户自己选择分隔符。快速的解决方法是\d\d.\d\d.\d\d.。看上去不错,会匹配02/12/03 。但是麻烦是,它也会匹配02512703,这不是我们想看到的。

\d\d[- /.]\d\d[- /.]\d\d 才是较好的解决方案。注意,点符号.在字符集中不属于元字符,所以你不需要转义。

但这个正则表达式仍然不完美,因为她匹配99/99/99,[0-1]\d[- /.][0-3]\d[- /.]\d\d稍微完美一点,但是它匹配19/39/99。要多完美,取决于想怎么做。如果用来验证用户输入,这不完美。如果用来转换数据文件,这个可能就足够。

使用否定的字符集替代点符号.

假设你想要匹配一个引号包括的字符串,听起来简单。引号里包含任何个数的任何字符,".*"似乎很不错,点符号.匹配任何字符,星号*表示重复任何次数,包括0,如果你把正则表达式应用于Put a "string" between double quotes这句话,很好的匹配"string"。如果应用于 Houston, we have a problem with "string one" and "string two". Please respond.那么匹配的是?"string one" and "string two"。不是我们想要的,因为星号*是贪婪的。

在日期匹配的例子中,我们用字符集替代点符号来改善正则表达式,这里我们也是相同做法。对于双引号内的字符串的定义是错误的。不想让任何字符以任何次数的形式出现在引号中,而是希望任何不是双引号和换行符的字符以任何次数的形式出现在双引号内。所以恰当的正则表达式是"[^"\r\n]*"。


















本文转自cnn23711151CTO博客,原文链接:http://blog.51cto.com/cnn237111/715991  ,如需转载请自行联系原作者