正则表达式的环视实际应用案例

一、千位分隔符案例(一)

逆序环视和顺序环视结合应用。

**需求:**数字格式化成用 , 分隔的货币格式。

正则表达式:(?n)(?<=\d)(?<!\.\d*)(?=(\d{3})+(\.|$))

测试代码:

double[] data = new double[] { 
0, 12, 123, 1234, 12345, 123456, 1234567, 123456789, 1234567890, 12.345, 
123.456, 1234.56, 12345.6789, 123456.789, 1234567.89, 12345678.9 
};foreach (double d in data) {richTextBox2.Text += "源字符串:" + d.ToString().PadRight(15) + "格式化:" + Regex.Replace(d.ToString(), @"(?n)(?<=\d)(?<!\.\d*)(?=(\d{3})+(\.|$))", ",") + "\n";
}

输出结果:

源字符串:0              格式化:0源字符串:12             格式化:12源字符串:123            格式化:123源字符串:1234           格式化:1,234源字符串:12345          格式化:12,345源字符串:123456         格式化:123,456源字符串:1234567        格式化:1,234,567源字符串:123456789      格式化:123,456,789源字符串:1234567890     格式化:1,234,567,890源字符串:12.345         格式化:12.345源字符串:123.456        格式化:123.456源字符串:1234.56        格式化:1,234.56源字符串:12345.6789     格式化:12,345.6789源字符串:123456.789     格式化:123,456.789源字符串:1234567.89     格式化:1,234,567.89源字符串:12345678.9     格式化:12,345,678.9

实现分析:

首先根据需求可以确定是把一些特定的位置替换为 ,,接下来就是分析并找到这些位置的规律,并抽象出来以正则表达式来表示。

  1. 这个位置的左侧必须为数字

  2. 这个位置右侧到出现 . 或结尾为止,必须是数字,且数字的个数必须为 3 的倍数

  3. 这个位置左侧相隔任意个数字不能出现 .

由以上三条,就可以完全确定这些位置,只要实现以上三条,组合一下正则表达式就可以了。

根据分析,最终匹配的结果是一个位置,所以所有子表达式都要求是零宽度。

  1. 是对当前所在位置左侧附加的条件,所以要用到逆序环视,因为要求必须出现,所以是肯定的,符合这一条件的子表达式即为 (?<=\d)

  2. 是对当前所在位置右侧附加的条件,所以要用到顺序环视,也是要求出现,所以是肯定的,是数字,且个数为3的倍数,即 (?=(\d{3})+),到出现 . 或结尾为止,即 (?=(\d{3})+(\.|$))

  3. 是对当前所在位置左侧附加的条件,所以要用到逆序环视,因为要求不能出现,所以是否定的,即 (?<!\.\d*)

因为零宽度的子表达式是非互斥的,最后匹配的都是同一个位置,所以先后顺序是不影响最后的匹配结果的,可以任意组合,只是习惯上把逆序环视写在左侧,顺序环视写在右侧。

说明:这里只是为了说明环视的使用而举的一个例子,实际上这个需求直接用 string.Format 就可以做到。

二、千位分隔符案例(二)

千位分隔符,顾名思义,就是数字每隔三位添加一个逗号。这是参考西方的习惯,在数字之中加入一个符号,避免因数字太长难以直观的看出它的值。

那么怎么将一串数字转化为千位分隔符形式呢?

var str = "1234567890.9876";
console.log((+str).toLocaleString()); // 1,234,567,890.988

如上,toLocaleString() 返回当前对象的“本地化”字符串形式。

  1. 如果该对象是 Number 类型,那么将返回该数值的按照特定符号分割的字符串形式;
  2. 如果该对象是 Array 类型,那么先将数组中的每项转化为字符串,然后将这些字符串以指定分隔符连接起来并返回。

我们尝试使用环视来处理下:

var str = 1234567890;
function thousand(str){return str.replace(/(?!^)(?=([0-9]{3})+$)/g,','); // 进行了好多次迭代匹配,匹配到 3 个位置,把匹配到的位置替换成逗号
}
console.log(thousand(str));//"1,234,567,890"
console.log(thousand("123456"));//"123,456"
console.log(thousand("1234567879876543210"));//"1,234,567,879,876,543,210"

上述使用到的正则表达式分为两块 (?!^)(?=([0-9]{3})+$)。我们先来看后面的部分,然后逐步分析之。

  1. [0-9]{3} 表示连续3位数字;
  2. ([0-9]{3})+ 表示连续3位数字至少出现一次或更多次;
  3. ([0-9]{3})+$ 直到字符串末尾;
  4. 那么 (?=([0-9]{3})+$) 就表示匹配一个零宽度的位置,并且从这个位置到字符串末尾,中间拥有至少 1 组以3个数字为 1 组的数字(即 3 的正整数倍得到数值为数字的个数;就是 3 乘以 1,3 乘以 2,以此得到的乘积为个数的数字);
  5. 正则表达式使用全局匹配 g,表示匹配到一个位置后,它会继续匹配,直至匹配不到;
  6. 将这个位置替换为逗号,实际上就是每 3 位数字添加一个逗号;
  7. 当然对于字符串 123456 这种刚好拥有 3 的正整数倍个数的数字,当然不能在1前面添加逗号,那么使用 (?!^) 就指定了这个替换的位置不能为起始位置。

三、顺序肯定环视

假如现在,js 通过 ajax 获取到一段 html 代码如下:

var responseText = "<div data='dev.xxx.txt'></div><img src='dev.xxx.png'/>";

现我们需要替换 img 标签的 src 属性中的 dev 字符串为 test 字符串。

  1. 由于上述 responseText 字符串中包含至少两个子字符串 dev,显然不能直接 replace 字符串 devtest

  2. 同时由于 js 中不支持逆序环视,我们也不能在正则中判断前缀为 src=',然后再替换 dev

  3. 我们注意到 img 标签的 src 属性以 .png 结尾,基于此,就可以使用顺序肯定环视。

var reg = /dev(?=[^']*png)/; //为了防止匹配到第一个dev, 通配符前面需要排除单引号或者是尖括号
var str = responseText.replace(reg,"test");
console.log(str);//<div data='dev.xxx'></div><img src='test.xxx.png' />

当然,以上不止顺序肯定环视一种解法,捕获性分组同样可以做到。那么环视高级在哪里呢?环视高级的地方就在于它通过一次捕获就可以定位到一个位置,对于复杂的文本替换场景常有奇效,而分组则需要更多的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/333737.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软件工程专插本_2021年专插本部分招生专业(拟),广科/广东理工/华商/培正/松田/工商大!...

小师姐从各专插本交流群中收集到了6所院校的2021年本科插班生拟招生专业&#xff1a;广东理工学院、广东科技学院、广东财经大学华商学院、广州大学松田学院、广东培正学院、广东工商职业技术大学。ps&#xff1a;以下只是拟招生专业&#xff0c;具体还是以考试院公布的为准。另…

Requests库实战(一)---网页采集器

网页采集器User-Agent伪装完整代码功能&#xff1a;通过动态url来实现用户输入搜索关键字&#xff0c;返回搜索到的页面。User-Agent伪装 一种反爬机制。 原理&#xff1a;网站的服务器会检测对于请求的载体身份标识&#xff0c;如果检测到请求的载体身份标识为某一款浏览器&a…

ES6 对正则表达式的扩展

文章目录修饰符 y修饰符 uECMAScript 6.0&#xff08;以下简称 ES6&#xff09;是 JavaScript 语言的下一代标准&#xff0c;已经在 2015 年 6 月正式发布了。它的目标&#xff0c;是使得 JavaScript 语言可以用来编写复杂的大型应用程序&#xff0c;成为企业级开发语言。修饰符…

transformer机制讲解_【核心代码解读】Transformer-XL

[论文] Transformer-XL: Attentive Language Models Beyond a Fixed-Length Context​arxiv.orgMotivationTransformer在预训练阶段&#xff0c;设置了固定序列长度max_len的上下文&#xff0c;finetuning阶段&#xff0c;模型不能获取大于max_len的上下文依赖&#xff1b;Tran…

Neo4j导入:java.lang.IllegalStateException:不支持在单个导入中混合指定和未指定的组所有物...

休息片刻之后&#xff0c;我最近一直在使用Neo4j导入工具 &#xff0c;并遇到了我最初不理解的有趣的错误消息。 我有一些CSV文件&#xff0c;其中包含要导入Neo4j的节点。 它们的内容如下所示&#xff1a; $ cat people_header.csv name:ID(Person)$ cat people.csv "…

Requests库实战(二)---破解百度翻译

功能&#xff1a;爬取到页面中翻译后的文本数据 获取请求地址和请求方式 先输入dog翻译一下&#xff0c;发现是Ajax请求(动态实时刷新页面)&#xff0c;Ajax请求的数据包可以在网络的XHR中看到。找到输入dog的数据包&#xff0c;通过标头的表单数据kw:dog以及响应的结果就可以…

局部变量的赋值问题

int i 5; i 10;变量 i 在栈帧里面的局部变量表里面&#xff0c;这个局部变量表类似一个数组&#xff0c;里面包含了一些“槽位”来存放局部变量&#xff0c;i 这个变量&#xff0c;就是在局部变量表中的某一个槽位里面&#xff0c;并且 i 只会占用一个槽位&#xff0c;对变量…

php生成 sku_高并发下,php与redis实现的抢购、秒杀功能

抢购、秒杀是如今很常见的一个应用场景&#xff0c;主要需要解决的问题有两个&#xff1a;1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少&#xff08;"超卖"问题&#xff09;对于第一个问题&#xff0c;已经很容易想到用缓存来处理抢购&#xff0c;…

lambda :: -_无需再忙了:Lambda-S3缩略图,由SLAppForge Sigma钉牢!

lambda :: ->如果你还没有注意到了&#xff0c;我最近被唠叨试图开始使用时&#xff0c;我遭遇了陷阱AWSλ-S3正式例子 。 虽然大多数这些愚蠢的错误的指责是对我自己的懒惰&#xff0c;过度自尊和缺乏对细节的关注&#xff0c;我个人觉得&#xff0c;在开始与一家领先的无服…

Requests库实战(三)---爬取豆瓣电影详细信息

完整代码 爬取豆瓣电影的详细信息 地址&#xff1a;豆瓣电影动画 向下滑动时新增的数据也是Ajax请求&#xff0c;原理和上一个项目是一样的。唯一的不同是此处请求url携带了多个参数 import requests import json header{User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x6…

lineseparator_首选System.lineSeparator()以用Java编写系统相关的行分隔符字符串

lineseparatorJDK 7在java.lang.System类上引入了一个名为lineSeparator&#xff08;&#xff09;的新方法。 该方法不期待任何参数&#xff0c;并返回一个String &#xff0c;它表示“取决于系统的行分隔符字符串。” 此方法的Javadoc文档还指出System.lineSeparator() “始终…

JavaScript(JS)中与正则表达式有关的方法介绍

文章目录RegExpRegExp 对象的属性compiletestexecString一共有 7 个与正则表达式式相关的方法&#xff0c;这些方法分别来自于 RegExp 与 String 对象。RegExp RegExp 对象表示正则表达式, 主要用于对字符串执行模式匹配. 语法: new RegExp(pattern[, flags]) 参数 pattern …

Requests库实战(四)---爬取肯德基餐厅地址信息

功能&#xff1a;爬取查询后的肯德基餐厅的地址信息 地址&#xff1a;http://www.kfc.com.cn/kfccda/storelist/index.aspx 亮点是post请求的参数有两组&#xff1a;查询字符串参数&#xff0c;表单数据。 对于post请求,由于url中隐藏了许多参数&#xff0c;所以引入了表单数据…

显示请求_学习记录:HTTP的响应与请求amp;Curl

本文包含四个部分&#xff0c;简要介绍HTTP请求、HTTP响应、chrome开发者查看、与CURL命令。Part1&#xff1a;HTTP请求1GET请求指定的页面信息&#xff0c;并返回实体主体。2HEAD类似于get请求&#xff0c;只不过返回的响应中没有具体的内容&#xff0c;用于获取报头。3POST向…

java.线程池 线程数_如何在线程“ main”中修复异常java.lang.NoClassDefFoundError:Java中的org / slf4j / LoggerFactory...

java.线程池 线程数此错误表示您的代码或您在应用程序中使用的任何外部库都在使用SLF4J库 &#xff08;一个开放源代码日志记录库&#xff09;&#xff0c;但无法找到所需的JAR文件&#xff0c;例如slf4j-api-1.7.2.jar因此它是在线程“ main” java.lang.NoClassDefFoundError…

正则表达式实战---爬取多张图片

主要是分析网站图片的html源代码&#xff0c;来决定正则表达式如何写。 完整代码 #使用正则表达式爬取多张图片,亮点在于数据解析 #爬取网站&#xff1a;https://www.bilibili.com/read/cv11323037?fromsearch import requests import re import os image_pathimage if not …

JS(JavaScript) 使用捕获性分组处理文本模板,最终生成完整字符串

var tmp "An ${a} a ${b} keeps the ${c} away";// obj 是 json 对象 var obj {a:"apple",b:"day",c:"doctor" };/** *descript 声明定义一个函数 tmpl&#xff0c;该函数将文本模板对应的变量替换后返回 * */function tmpl(t,o){/*…

6 日期字符串转日期_Java日期时间API系列6-----Jdk8中java.time包中的新的日期时间API类...

因为Jdk7及以前的日期时间类的不方便使用问题和线程安全问题等问题&#xff0c;2005年&#xff0c;Stephen Colebourne创建了Joda-Time库&#xff0c;作为替代的日期和时间API。Stephen向JCP提交了一个规范&#xff0c;他本人作为规范的领导人&#xff0c;该规范就是JSR 310&am…

第一个JDK 10(18.3)候选版本(内部版本43)展示了新的版本控制方案

Mark Reinhold的帖子“ JDK 10&#xff1a;First Release Candidate ”宣布“在build 43中没有未解决的P1错误”&#xff0c;并将Build 43命名为最初的JDK 10 Release Candidate 。 Reinhold帖子还指向“ JDK 10 Early Access Builds ”页面&#xff0c;该页面包含发行说明的链…

安装Pytorch如何选择CUDA的版本

安装Pytorch时CUDA的选择Nvidia CUDA查看CUDA版本方法查看CUDA的驱动API版本查看CUDA的运行API版本查看官方CUDA的运行API版本方法1方法2查看Anaconda里cudatoolkit包版本CUDA是一个并行计算平台和编程模型&#xff0c;能够使得使用GPU进行通用计算变得简单和优雅。Nvidia官方提…