《正则表达式经典实例(第2版)》——2.21 把部分的正则匹配添加到替代文本中

简介: 实例2.10讲解了在正则表达式中如何使用捕获分组来多次匹配相同的文本。在正则表达式中,每个捕获分组匹配到的文本在每次成功匹配之后都是可用的。你可以把部分或者所有捕获分组中的文本按照任意顺序甚至多次插入到替代文本中。

本节书摘来自异步社区《正则表达式经典实例(第2版)》一书中的第2章,第2.21节,作者: 【美】Jan Goyvaerts , Steven Levithan著,更多章节内容可以访问云栖社区“异步社区”公众号查看

2.21 把部分的正则匹配添加到替代文本中

问题描述
匹配任意10个数字的连续序列,如1234567890。并把这个序列转换成(美国)电话号码的常见格式,如(123) 456-7890,

解决方案
正则表达式

\b(\d{3})(\d{3})(\d{4})\b
正则选项:无
正则流派:.NET、Java、JavaScript、PCRE、Perl、Python、Ruby

替代文本

($1)●$2-$3
替代文本流派:.NET、Java、JavaScript、PHP、Perl
(${1})●${2}-${3}
替代文本流派:.NET、PHP、Perl
(\1)●\2-\3
替代文本流派:PHP、Python、Ruby

讨论
使用捕获分组的替代
实例2.10讲解了在正则表达式中如何使用捕获分组来多次匹配相同的文本。在正则表达式中,每个捕获分组匹配到的文本在每次成功匹配之后都是可用的。你可以把部分或者所有捕获分组中的文本按照任意顺序甚至多次插入到替代文本中。

一些流派,如Python和Ruby,在正则表达式和替代文本中对于反向引用使用相同的语法«1»。其他流派使用的则是Perl中的语法«$1»,也就是说使用的是美元符号而不是反斜杠。PHP对于两种语法都支持。

在Perl中,«$1»以及更高编号的分组实际上都是变量,它们的值会在每次正则匹配成功之后进行设置。你可以在代码中的任意地方使用它们,直到下一次正则匹配开始。.NET、Java、JavaScript和PHP只在替代文本语法中支持«$1»。这些编程语言还提供了其他在代码中访问捕获分组的方式。这会在第3章中详细解释。

$10及更多分组
本书中的所有正则流派都支持在单个正则表达式中使用最多99个捕获分组。在替代文本中,对于«$10»或«10»以及更多的分组则会产生二义性。这些可以被解释为是第10个捕获分组,或者是第一个捕获分组后跟着一个字面上的0。

.NET、XRegExp、PHP和Perl允许在数字周围使用花括号来澄清意图。«${10}» 总是代表第10个捕获分组,而«${1}0»则总是意味着第一个分组后跟着一个字面上的0。

Java和JavaScript对于«$10»使用了更加聪明的处理办法。如果在你的正则表达式中存在这个两位数的捕获分组的话,那么两位数字都会用于引用捕获分组。如果并不存在这么多捕获分组的话,那么只有第一个数字用来引用分组,这样第二个数字就当作了字面字符。因此«$23»只有在它存在的时候才被认为是第23个捕获分组。否则,它被当作是第2个捕获分组后面跟着一个字面上的«3»。

.NET、XRegExp、PHP、Perl、Python和Ruby总是把«$10»和«10»视为第10个捕获分组,而不管它们是否真的存在。如果它不存在的话,就会出现引用不存在的分组的状态。

对不存在的分组的引用
在这个实例的解决方案中的正则表达式拥有3个捕获分组。如果你在替代文本中输入了«$4»或«4»,就添加了一个对不存在的捕获分组的引用。这可能会触发如下的3种不同的行为。

Java、XRegExp和Python会报错,并且抛出异常或者返回错误消息。因此不要在这些流派中使用无效的反向引用。(事实上,你不应当在任何流派中使用无效的反向引用。)如果想要添加的是字面上的«$4»或«4»,就需要对美元符号或反斜杠进行转义。实例2.19中对此有详细的解释。

PHP、Perl和Ruby会替换在替代文本中所有的反向引用,也包括了那些指向不存在的分组的引用。不存在的分组显然不会捕获任何文本,因此对它们的引用也就简单地被替换为空。

最后,.NET和JavaScript(未使用XRegExp时)则把对不存在分组的引用当作是替代文本中的字面文本。

如果某个分组在正则表达式中存在,匹配中却没有捕获到任何东西,无论是什么流派,它仍然可以在替换文本中使用,只不过它们真实的值是空串。

使用命名捕获的解决方案
正则表达式

\b(?<area>\d{3})(?<exchange>\d{3})(?<number>\d{4})\b
正则选项:无
正则流派:.NET、Java 7、XRegExp、PCRE 7、Perl 5.10、Ruby 1.9
\b(?'area'\d{3})(?'exchange'\d{3})(?'number'\d{4})\b
正则选项:无
正则流派:.NET、PCRE 7、Perl 5.10、Ruby 1.9
\b(?P<area>\d{3})(?P<exchange>\d{3})(?P<number>\d{4})\b
正则选项:无
正则流派:PCRE、Perl 5.10、Python

替代文本

(${area})●${exchange}-${number}
替代文本流派:.NET、Java 7、XRegExp
(\g<area>)●\g<exchange>-\g<number>
替代文本流派:Python
(\k<area>)●\k<exchange>-\k<number>
替代文本流派:Ruby 1.9
(\k'area')●\k'exchange'-\k'number'
替代文本流派:Ruby 1.9
($+{area})●$+{exchange}-$+{number}
替代文本流派:Perl 5.10
($1)●$2-$3
替代文本流派:PHP

支持命名捕获的流派
如果你在正则表达式中使用了命名捕获分组,那么在.NET、Java 7、XRegExp、Python和Ruby 1.9中允许在替代文本中使用命名反向引用。在替代文本使用的命名反向引用语法与正则表达式中使用的不同。

Ruby在替代文本中使用与其在正则表达式中一样的反向引用语法。对于Ruby 1.9中的命名捕获分组,它的语法是«k»或«k'group'»。你可以选择尖括号也可以选择单引号,只看哪种方便。

Perl 5.10及以后版本将命名捕获分组匹配的文本保存在散列变量(hash)%+中。你可以使用$+{name}获得名为“name”的分组匹配的文本。Perl在替代文本中插入变量值,所以在替代文本中可以把«$+{name}»视为命名反向引用。

PHP(使用PCRE)在正则表达式中支持命名捕获分组,但是在替代文本中则不支持。你可以在替代文本中使用编号的反向引用来引用正则表达式中的命名捕获分组。PCRE会对所有命名和不命名的分组进行编号,顺序是从左向右。

.NET、Java 7、XRegExp、Python和Ruby 1.9同样允许使用编号来引用命名分组。然而,.NET对于命名分组则采用了不同的编号策略,这在实例2.11中已经进行了讲解。不推荐在.NET、Java 7、XRegExp、Python或Ruby中混合使用命名和编号。要么所有分组都命名,要么所有分组都不命名。对于命名分组,应该总是使用命名的反向引用。

相关文章
|
机器学习/深度学习 前端开发 Windows
【夯实技术基本功】「底层技术原理体系」全方位带你认识和透彻领悟正则表达式(Regular Expression)的开发手册(正则符号深入解析 )
【夯实技术基本功】「底层技术原理体系」全方位带你认识和透彻领悟正则表达式(Regular Expression)的开发手册(正则符号深入解析 )
208 0
|
Java 程序员
Java 异常处理与正则表达式详解,实例演练及最佳实践
在 Java 代码执行期间,可能会发生各种错误,包括程序员编码错误、用户输入错误以及其他不可预料的状况。 当错误发生时,Java 通常会停止并生成错误消息,这个过程称为抛出异常。 try...catch 语句 try 语句允许您定义一段代码块,并在其中测试是否发生错误。 catch 语句允许您定义一段代码块,当 try 块中发生错误时执行该代码块。 try 和 catch 关键字成对使用,语法如下:
215 0
|
机器学习/深度学习 存储 JavaScript
正则表达式基础语法与Java、JS使用实例
正则表达式基础语法与Java、JS使用实例
202 1
|
JavaScript 前端开发
JS正则表达式:常用正则手册/RegExp/正则积累(一)
JS正则表达式:常用正则手册/RegExp/正则积累
383 1
|
存储 JavaScript 安全
JS正则表达式:常用正则手册/RegExp/正则积累(二)
JS正则表达式:常用正则手册/RegExp/正则积累
275 0
正则表达式(有关String当中,有关正则的方法)
正则表达式(有关String当中,有关正则的方法)
|
SQL 数据处理 数据库
SQL正则表达式应用:文本数据处理的强大工具——深入探讨数据验证、模式搜索、字符替换等核心功能及性能优化和兼容性问题
【8月更文挑战第31天】SQL正则表达式是数据库管理和应用开发中处理文本数据的强大工具,支持数据验证、模式搜索和字符替换等功能。本文通过问答形式介绍了其基本概念、使用方法及注意事项,帮助读者掌握这一重要技能,提升文本数据处理效率。尽管功能强大,但在不同数据库系统中可能存在兼容性问题,需谨慎使用以优化性能。
249 0
|
SQL 分布式计算 算法
【python】python指南(三):使用正则表达式re提取文本中的http链接
【python】python指南(三):使用正则表达式re提取文本中的http链接
194 0
|
Rust 监控 安全
【专栏】`ripgrep`(rg)是Linux下快速、内存高效的文本搜索工具,用Rust编写,支持PCRE2正则表达式
【4月更文挑战第28天】`ripgrep`(rg)是Linux下快速、内存高效的文本搜索工具,用Rust编写,支持PCRE2正则表达式。相比`grep`,它在处理大文件和复杂模式时更具优势。安装`rg`可通过软件包管理器,如在Debian系系统中使用`sudo apt install ripgrep`。基本用法包括简单搜索、递归搜索、忽略大小写、显示行号等。高级功能包括固定字符串搜索、多文件匹配、并行搜索、排除选项和区域搜索。适用于日志分析、代码审查等场景,是提升工作效率的利器。
1376 4