本网站上的更多内容 |
简介 |
正则表达式快速入门 |
正则表达式教程 |
替换字符串教程 |
应用程序和语言 |
正则表达式示例 |
正则表达式参考 |
替换字符串参考 |
书籍评论 |
可打印 PDF |
关于本网站 |
RSS 源和博客 |
在正则表达式中,点号或句点是最常用的 元字符 之一。不幸的是,它也是最常被误用的元字符。
点号匹配单个字符,而不考虑该字符是什么。唯一的例外是换行符。在本教程中讨论的所有正则表达式风格中,点号默认情况下不匹配换行符。
此异常的存在主要出于历史原因。使用正则表达式的第一个工具是基于行的。它们逐行读取文件,并将正则表达式分别应用于每一行。其效果是,使用这些工具时,字符串永远不能包含换行符,因此点永远不能与它们匹配。
现代工具和语言可以将正则表达式应用于非常大的字符串,甚至整个文件。除了 VBScript,此处讨论的所有正则表达式风格都具有使点匹配所有字符(包括换行符)的选项。较早的 JavaScript 实现也没有此选项。它在 ECMAScript 2018 规范中正式添加。
在 PowerGREP 中,勾选标记为“点匹配换行符”的复选框,以使点匹配所有字符。在 EditPad Pro 中,启用“点”或“点匹配换行符”搜索选项。
在 Perl 中,点也匹配换行符的模式称为“单行模式”。这有点不幸,因为很容易将此术语与“多行模式”混淆。多行模式仅影响 锚点,而单行模式仅影响点。您可以通过在正则表达式代码后添加 s 来激活单行模式,如下所示:m/^regex$/s;。
其他语言和正则表达式库采用了 Perl 的术语。在使用 .NET 的 Regex 类 时,您可以通过指定 RegexOptions.Singleline 来激活此模式,例如 Regex.Match("string", "regex", RegexOptions.Singleline)。
在 JavaScript(为了与旧浏览器兼容)和 VBScript 中,可以使用 字符类,例如 [\s\S] 来匹配任何字符。此字符匹配空格字符(包括换行符)或非空格字符。由于所有字符都是空格或非空格,因此此字符类匹配任何字符。不要使用 (\s|\S) 这样的交替,这会很慢。当然不要使用 (.|\s),因为空格和制表符既可以被 . 匹配,也可以被 \s 匹配,这会导致灾难性的回溯。
在所有 Boost 的正则表达式语法中,点默认匹配换行符。Boost 的 ECMAScript 语法允许您使用 regex_constants::no_mod_m 关闭此功能。
虽然点在各种正则表达式风格中都得到支持,但它们将哪些字符视为换行符却存在显著差异。所有风格都将换行符 \n 视为换行符。UNIX 文本文件使用单个换行符终止行。本教程中讨论的所有脚本语言都不将任何其他字符视为换行符。即使在通常使用 \r\n 对来换行的 Windows 上,这也不是问题。这是因为这些脚本语言在默认情况下以文本模式读取和写入文件。在 Windows 上运行时,在读取文件时 \r\n 对会自动转换为 \n,而 \n 会自动写入文件为 \r\n。
std::regex、XML Schema 和 XPath 也将回车 \r 视为换行符。在此基础上,JavaScript 添加了 Unicode 行分隔符 \u2028 和段落分隔符 \u2029。 Java 包含这些分隔符,外加拉丁语-1 下一行控制字符 \u0085。 Boost 将换页符 \f 添加到列表中。只有 Delphi 和 JGsoft 风格 支持所有 Unicode 换行符,并使用垂直制表符完成了组合。
.NET 在将除 \n 之外的字符视为换行符的风格列表中明显缺失。与根植于 UNIX 世界的脚本语言不同,.NET 是一个 Windows 开发框架,不会自动从读取的文本文件中删除回车符。如果您将 Windows 文本文件整体读入字符串,它将包含回车符。如果您在该字符串上使用正则表达式 abc.*,而不设置 RegexOptions.SingleLine,那么它将匹配 abc 以及同一行上紧随其后的所有字符,以及该行末尾的回车符,但不会匹配其后的换行符。
一些风格允许您控制哪些字符应视为换行符。Java 具有 UNIX_LINES 选项,使其仅将 \n 视为换行符。 PCRE 具有允许您在仅 \n、仅 \r、\r\n 或所有 Unicode 换行符之间进行选择的选项。
在 POSIX 系统中,POSIX 区域设置决定哪些字符是换行符。C 区域设置仅将换行符 \n 视为换行符。Unicode 区域设置支持所有 Unicode 换行符。
Perl 5.12 和 PCRE 8.10 引入了 \N,它与点号一样,匹配任何不是换行符的单个字符。与点号不同,\N 不受“单行模式”影响。\N. 启用单行模式,然后匹配任何不是换行符的字符,后跟任何字符,无论它是否是换行符。
控制哪些字符被视为换行符的 PCRE 选项对 \N 的影响与它们对点号的影响完全相同。
PHP 5.3.4 和 R 2.14.0 也支持 \N,因为它们的正则表达式支持基于 PCRE 8.10 或更高版本。JGsoft V2 也支持 \N。
点号是一个非常强大的正则表达式元字符。它允许你偷懒。输入一个点号,在对有效数据测试正则表达式时,一切匹配正常。问题在于,正则表达式在不应该匹配的情况下也匹配。如果你刚接触正则表达式,其中一些情况一开始可能并不那么明显。
我们用一个简单的例子来说明这一点。假设我们想要匹配 mm/dd/yy 格式的日期,但我们希望让用户选择日期分隔符。快速解决方案是 \d\d.\d\d.\d\d。乍一看似乎很好。它可以很好地匹配 02/12/03 这样的日期。问题是:02512703 也被此正则表达式视为有效日期。在此匹配中,第一个点号匹配 5,第二个匹配 7。显然不是我们想要的。
\d\d[- /.]\d\d[- /.]\d\d 是一个更好的解决方案。此正则表达式允许使用连字符、空格、点号和正斜杠作为日期分隔符。请记住,点号在 字符类 中不是元字符,因此我们不需要用反斜杠对其进行转义。
此正则表达式还远不完美。它将 99/99/99 匹配为有效日期。[01]\d[- /.][0-3]\d[- /.]\d\d 虽然更进一步,但它仍然匹配 19/39/99。您希望正则表达式有多完美取决于您想要用它做什么。如果您要验证用户输入,则它必须完美。如果您要从每次以相同方式生成文件的已知源解析数据文件,那么我们的最后一次尝试可能足以在不出现错误的情况下解析数据。您可以在示例部分找到一个 更好的正则表达式来匹配日期。
否定字符类通常比点更合适。否定字符类 教程部分解释了重复运算符 星号和加号,其中更详细地介绍了这一点。但该警告非常重要,因此在此也需要提到它。我们再次通过一个示例来说明。
假设您想匹配一个双引号字符串。听起来很简单。我们可以在双引号之间包含任意数量的任何字符,因此 ".*" 似乎可以很好地完成这项工作。点匹配任何字符,星号允许点重复任意次数,包括零次。如果您对 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]*"。如果您的风格支持 简写 \v 来匹配任何换行符,那么 "[^"\v]*" 是更好的解决方案。
| 快速入门 | 教程 | 工具和语言 | 示例 | 参考 | 书籍评论 |
| 简介 | 目录 | 特殊字符 | 不可打印字符 | 正则表达式引擎内部 | 字符类 | 字符类减法 | 字符类交集 | 简写字符类 | 点 | 锚 | 单词边界 | 交替 | 可选项目 | 重复 | 分组和捕获 | 反向引用 | 反向引用,第 2 部分 | 命名组 | 相对反向引用 | 分支重置组 | 自由间距和注释 | Unicode | 模式修饰符 | 原子分组 | 独占量词 | 前瞻和后顾 | 前瞻和后顾,第 2 部分 | 将文本排除在匹配之外 | 条件 | 平衡组 | 递归 | 子例程 | 无限递归 | 递归和量词 | 递归和捕获 | 递归和反向引用 | 递归和回溯 | POSIX 方括号表达式 | 零长度匹配 | 继续匹配 |
页面 URL:https://regexper.cn/dot.html
页面上次更新时间:2021 年 8 月 12 日
网站上次更新时间:2024 年 3 月 15 日
版权所有 © 2003-2024 Jan Goyvaerts。保留所有权利。