本网站上的更多内容 |
简介 |
正则表达式快速入门 |
正则表达式教程 |
替换字符串教程 |
应用程序和语言 |
正则表达式示例 |
正则表达式参考 |
替换字符串参考 |
书籍评论 |
可打印 PDF |
关于本网站 |
RSS 源和博客 |
原子组是一种组,当正则表达式引擎退出该组时,会自动丢弃该组内任何标记记住的所有回溯位置。原子组是无捕获的。语法为 (?>组)。 环视组也是原子的。大多数现代正则表达式风格都支持原子分组,包括 JGsoft 风格、Java、PCRE、.NET、Perl、Boost 和 Ruby。其中大多数还支持 占有量词,这本质上是原子分组的一种符号便利。 Python 从 Python 3.11 版本开始支持原子分组和占有量词。
一个示例将阐明原子组的行为。正则表达式 a(bc|b)c(捕获组)匹配 abcc 和 abc。正则表达式 a(?>bc|b)c(原子组)匹配 abcc 但不匹配 abc。
应用于 abc 时,两个正则表达式都将匹配 a 到 a、bc 到 bc,然后 c 将无法匹配字符串末尾。此处它们的路径不同。带有捕获组的正则表达式已记住交替的回溯位置。该组将放弃其匹配,b 然后匹配 b,c 匹配 c。找到匹配项!
然而,带有原子组的正则表达式在匹配 bc 后退出了原子组。此时,该组内标记的所有回溯位置都会被丢弃。在此示例中,交替在字符串第二个位置尝试 b 的选项被丢弃。结果,当 c 失败时,正则表达式引擎没有其他可尝试的替代方案。
当然,上面的示例并不是很有用。但它确实非常清楚地说明了原子分组如何消除某些匹配。或者更重要的是,它消除了某些匹配尝试。
考虑正则表达式 \b(integer|insert|in)\b 和主题 integers。显然,由于单词边界,它们不匹配。不太明显的是,正则表达式引擎将花费相当多的精力来弄清楚这一点。
\b 在字符串的开头匹配,integer 匹配 integer。正则表达式引擎注意到组中还有两个备选方案,并继续使用 \b。这无法在 r 和 s 之间匹配。因此,引擎回溯以尝试组内的第二个备选方案。第二个备选方案匹配 in,但随后无法匹配 s。因此,引擎再次回溯到第三个备选方案。in 匹配 in。\b 这次在 n 和 t 之间失败。正则表达式引擎不再记住回溯位置,因此它声明失败。
这是很多工作,以弄清楚 integers 不在我们的单词列表中。我们可以通过告诉正则表达式引擎,如果它在匹配 integer 后无法匹配 \b,那么它不应该尝试任何其他单词来优化这一点。我们在主题字符串中遇到的单词是一个较长的单词,它不在我们的列表中。
我们可以通过将捕获组转换为原子组来实现这一点:\b(?>integer|insert|in)\b。现在,当 integer 匹配时,引擎将从原子组退出,并丢弃为交替存储的回溯位置。当 \b 失败时,引擎会立即放弃。在扫描大型文件以查找长关键字列表时,这种节省可能是显着的。当您的备选方案包含重复标记(更不用说重复组)导致灾难性回溯时,这种节省将至关重要。
不要过快地将所有组设为原子组。正如我们在上面的第一个示例中看到的那样,原子分组也会排除有效的匹配。比较当应用于 insert 时 \b(?>integer|insert|in)\b 和 \b(?>in|integer|insert)\b 的行为。前一个正则表达式匹配,而后一个失败。如果组不是原子组,则两个正则表达式都会匹配。请记住,交替从左到右尝试其备选方案。如果第二个正则表达式匹配 in,则由于原子组,它不会尝试其他两个备选方案。
| 快速入门 | 教程 | 工具和语言 | 示例 | 参考 | 书籍评论 |
| 简介 | 目录 | 特殊字符 | 不可打印字符 | 正则表达式引擎内部 | 字符类 | 字符类减法 | 字符类交集 | 简写字符类 | 点 | 锚 | 单词边界 | 交替 | 可选项 | 重复 | 分组和捕获 | 反向引用 | 反向引用,第 2 部分 | 命名组 | 相对反向引用 | 分支重置组 | 自由间距和注释 | Unicode | 模式修饰符 | 原子分组 | 所有格量词 | 前瞻和后顾 | 前瞻和后顾,第 2 部分 | 将文本保留在匹配之外 | 条件 | 平衡组 | 递归 | 子例程 | 无限递归 | 递归和量词 | 递归和捕获 | 递归和反向引用 | 递归和回溯 | POSIX 方括号表达式 | 零长度匹配 | 继续匹配 |
页面 URL:https://regexper.cn/atomic.html
页面上次更新时间:2022 年 11 月 21 日
网站上次更新时间:2024 年 3 月 15 日
版权所有 © 2003-2024 Jan Goyvaerts。保留所有权利。