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

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

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

正则表达式:(?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' />

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

正则表达式的环视实际应用案例相关推荐

  1. [Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例

    欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都将结合案例.代码和作者的经验讲 ...

  2. 【C#进阶三】C#正则表达式的使用及常用案例(Regex.IsMatch、Regex.Match,match.NextMatch、Regex.Matches、Regex.Replace等)(实践篇)

    文章目录 1. 匹配正则表达式模式:Regex.IsMatch 2.提取单个匹配项或第一个匹配项:Regex.Match(),match.NextMatch() 3.提取所有匹配项Regex.Matc ...

  3. c#使用正则表达式获取TR中的多个TD_[Python从零到壹] 四.网络爬虫之入门基础及正则表达式抓取博客案例...

    首先祝大家中秋节和国庆节快乐,欢迎大家来到"Python从零到壹",在这里我将分享约200篇Python系列文章,带大家一起去学习和玩耍,看看Python这个有趣的世界.所有文章都 ...

  4. java 正则表达式匹配数字_java正则表达式匹配所有数字的案例

    用于匹配的正则表达式为 :([1-9]\d*\.?\d*)|(0\.\d*[1-9]) ( [1-9] :匹配1~9的数字: \d :匹配数字,包括0~9: * :紧跟在 \d 之后,表明可以匹配零个 ...

  5. 正则表达式的环视深度剖析

    文章目录 一.环视基础 二.顺序环视匹配过程 (一)顺序肯定环视匹配过程 (二)顺序否定环视匹配过程 三.逆序环视匹配过程 (一)逆序环视基础 (二)逆序肯定环视匹配过程 1. 逆序表达式的长度固定, ...

  6. java正则 环视_正则表达式之环视(java)

    这段代码中真正匹配到的字符串是"ld",所谓的顺序环视就是在匹配这个字符串前的那个位置. 相信大家现在应该能够推测出逆序环视了吧.匹配的是ld后面那个位置. 环视的例子 理解了上诉 ...

  7. java正则表达式简单总结以及个别案例(手机号码,邮箱,座机号码)

    记录一下学习历程,方便自己回头看看 首先使用正则表达式的格式是这样 String str="1asdf978"; str.matches("\\d{6,20}" ...

  8. Python基础教程:正则表达式re高级用法与案例

    search 需求:匹配出文章阅读的次数 import reret = re.search(r"\d+", "阅读次数为 9999") ret.group() ...

  9. 深入理解正则表达式环视的概念与用法

    在<深入理解正则表达式高级教程-环视>中已经对环视做了简单的介绍,但是,可能还有一些读者比较迷惑,今天特意以专题的形式,深入探讨一下正则表达式的环视的概念与用法. 深入理解正则表达式环视的 ...

最新文章

  1. 硬核!如何全面系统地自学 Java ?(必看)
  2. BCH为什么要把自身打造成多元化平台
  3. Spring could 使用Feign超时问题
  4. ubunto用户切换
  5. vue中如何实现点击某个地方,让echarts生成的图表发生变化
  6. anguarjs 上传图片预览_JS控制上传图片个数,预览上传图片
  7. python tableview绑定字典_在QTableView中使用各种自定义委托
  8. 软件工程2第一次作业
  9. 阴险的codeproject
  10. python计算矩阵的散度_数据集相似度度量之KLJS散度
  11. AMS1117降压电路
  12. 使用格拉姆角场(GAF)以将时间序列数据转换为图像
  13. Android Studio 全局搜索快捷键
  14. android sdk安装配置win10环境
  15. c语言数组中逗号的作用,c语言练习(4)--逗号分割字符串形成二维数组
  16. 学习完美方块小游戏(cocos creator)
  17. ssd的smt_探访固态硬盘工厂,揭秘 SSD 生产过程
  18. C# Color 颜色对照表
  19. 弱口令到底是什么牛马?
  20. 2015移动安全漏洞年报

热门文章

  1. boot gwt_带Spring Boot的GWT
  2. groovy grails_在Grails战争中添加一个“精简”的Groovy Web控制台
  3. java关键字和标识符_Java数据类型和标识符
  4. unsafe jdk9_JDK 9清单:Project Jigsaw,sun.misc.Unsafe,G1,REPL等
  5. 产品原型示例_原型设计模式示例
  6. weld焊接_玩Weld-Probe –一站式查看CDI的所有方面
  7. HttpClient 4 API –获取状态码-getStatusLine()。getStatusCode()示例
  8. activemq 实例_在一台计算机上运行多个ActiveMQ实例
  9. 正义联盟的Spring靴
  10. 设计模式 原型模式_原型设计模式:创建另一个小车