.NET 中的正则表达式是基于 Perl 5 的正则表达式。

超时

从 .NET Framework 4.5 开始,正则表达式支持在匹配操作中指定超时时间。如果匹配超时,就会抛出 RegexMatchTimeoutException

所有方法都增加了带超时时间参数的重载:

public static Match Match(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

public static MatchCollection Matches(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

public static string Replace(string input, string pattern, string replacement, RegexOptions options, TimeSpan matchTimeout);

public static string[] Split(string input, string pattern, RegexOptions options, TimeSpan matchTimeout);

如果应用程序需要处理任意的正则表达式(例如在高级搜索对话框中)则务必使用该参数以防止一些恶意的正则表达式导致无限计算。

编译正则表达式

RegexOptions.Compiled 选项将会使 Regex 实例通过轻量级的代码生成器动态地构建并编译针对特定正则表达式的代码,提高匹配速度。

模式修正符

模式修正符不仅可以打开,还可以关闭。如下示例,先打开忽略大小写,再关闭忽略大小写,所以匹配结果是 Aa

Regex.Match("AAAa", "(?i)a(?-i)a").Value;    // Aa

零宽断言

现在要写一个用于验证密码是否符合要求的正则表达式,要求是至少包含一个数字。

这个很简单,如下就可以了

Regex.IsMatch("12345678", "\d");

现在加一个条件,长度要大于 6 位。似乎用一个正则无法实现。

其实是可以的,用零宽断言中的 正向先行断言 就可以了。

正向先行断言 (?=exp),一般用来匹配 exp 之前的内容。例如下面个例子,要取出姓名,需要匹配 之前的内容。

Regex.Match("姓名张三,男,30 岁", "(?<=姓名).*?(?=,)").Value;  // 张三

其实,正确的理解是:正向先行断言,匹配成功之后,会退回起始位置,然后继续之后的匹配。

这里最重要的一点是,匹配成功以后退回起始位置,所以,对它正确的理解是,一个前向条件判断。

那么上面的密码至少包含一个数字,且长度大于 6 就好实现了:

Regex.IsMatch("abcde6", @"(?=.*\d).{6,}");

我们再增加一点难度,密码要求符合如下条件:

  • 至少 8 位
  • 至少包含一个数字
  • 至少包含一个小写字母
  • 至少包含一个大写字母
string pattern = @"(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}";
Regex.IsMatch("12345678", pattern); // false
Regex.IsMatch("1234567a", pattern); // false
Regex.IsMatch("123456aA", pattern); // true

分割字符串

分割字符串分隔符不会包含在结果中,若要将分隔符包含在结果中,则可以将表达式包含在正前向条件中。

foreach (string s in Regex.Split("oneTwoThree", "(?=[A-Z])"))
Console.WriteLine(s); // one
// Two
// Three

分组

正则表达式中可以通过 \n 语法来引用索引为 n 的分组。

var m = Regex.Matches("pop pope peep", @"\b(\w)\w+\1\b");

// pop
// peep

命名捕获分组语法:

(?'组名'表达式)(?<组名>表达式)

引用命名分组语法:

\k'组名'\k<组名>

替换并分割文本

替换字符串可以通过 $0 作为替代结构访问原始的匹配。$1$2 访问任意捕获的分组。对于命名分组,可以通过 ${name} 的方式进行访问。

给所有数字加上 <>:

Console.WriteLine(Regex.Replace("1 + 11 = 12", @"\d+", @"<$0>"));
// <1> + <11> = <12>

MatchEvaluator 委托

Replace 方法有一个重载,使用 MatchEvaluator 委托作为参数,替代 replacement。该委托将对每个匹配执行一次,并使用其返回结果替换原字符串中的值。

MatchEvaluator 委托定义:

public delegate string MatchEvaluator(Match match);

示例:

Console.WriteLine(Regex.Replace("1 + 11 = 12", @"\d+", m => (int.Parse(m.Value) * 10).ToString()));

// 10 + 110 = 120

C# 正则进阶的更多相关文章

  1. JavaScript正则进阶之路——活学妙用奇淫正则表达式

    原文收录在我的 GitHub博客 (https://github.com/jawil/blog) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 有些童鞋肯定 ...

  2. Python正则进阶

    目录 1.Python正则表达式模块 1.1 正则表达式处理字符串主要有四大功能 1.2 Python中re模块使用正则表达式的两种方法 1.3 正则表达式对象的常用方法 1.4 匹配对象的属性与方法 ...

  3. python 正则进阶

    1.group 除了简单地判断是否匹配之外,正则表达式还有提取子串的强大功能.用()表示的就是要提取的分组(Group).比如:^(\d{3})-(\d{3,8})$分别定义了两个组,可以直接从匹配的 ...

  4. python 正则进阶常用方法

    表达式 描述 正则表达式示例 符号 literal 匹配文本字符串的字面值literal foo rel1|rel2 匹配正则表达式rel1或rel2 foo|bar . 匹配任何字符(除了\n之外) ...

  5. js 正则进阶regexp

    一.匹配中文,英文字母和数字及_: const reg = /^[\u4e00-\u9fa5\w]+$/; const str1 = 'shangyy'; const str2 = '尚悦悦ww123 ...

  6. 关于正则表达式 C#

    读懂正则表达式就这么简单   一 前言 对于正则表达式,相信很多人都知道,但是很多人的第一感觉就是难学,因为看第一眼时,觉得完全没有规律可寻,而且全是一堆各种各样的特殊符号,完全不知所云. 其实只是对 ...

  7. js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^)

    js进阶正则表达式5几个小实例(原样匹配的字符在正则中原样输出)(取反^) 一.总结 原样匹配的字符在正则中原样输出:var reg4=/第[1-2][0-9]章/g //10-29 取反^:var ...

  8. js进阶正则表达式方括号(方括号作用)(js正则是在双正斜杠之中:/[a-z]/g)

    js进阶正则表达式方括号(方括号作用)(js正则是在双正斜杠之中:/[a-z]/g) 一.总结 方括号:范围 圆括号:选 大括号:数量 1.js正则是在双正斜杠之中: var reg2=/[a-z]/ ...

  9. js进阶js中支持正则的四个常用字符串函数(search march replace split)

    js进阶js中支持正则的四个常用字符串函数(search march replace split) 一.总结 代码中详细四个函数的用法 search march replace split 二.js进 ...

随机推荐

  1. 【题解】CF742E (二分图+构造)

    [题解]CF742E (二分图+构造) 自闭了CodeForces - 742E 给定的条件就是一个二分图的模型,但是有一些不同.不同就不同在可以出现相邻两个点颜色相同的情况. 构造常用方法之一是按奇 ...

  2. UCI 人口收入数据分析(python)

    一.项目介绍 UCI上有许多免费的数据集可以拿来练习,可以在下面的网站找寻 http://archive.ics.uci.edu/ml/datasets.html 这次我使用的是人口收入调查,里面会有 ...

  3. 从0开发3D引擎(五):函数式编程及其在引擎中的应用

    目录 上一篇博文 函数式编程的优点与缺点 优点 缺点 为什么使用Reason语言 函数式编程学习资料 引擎中相关的函数式编程知识点 数据 不可变数据 可变数据 函数 纯函数 高阶函数 柯西化 参考资料 ...

  4. Sample Code之Take a screenshot of a SceneView

    周末事情太多了,以后就工作日发布随笔吧.周末的话,看心情,也许也会发~ 今天的实例代码解析是Take a screenshot of a SceneView,也就是获取快照,话不多说,进入正题. 首先 ...

  5. Spring--2.Spring之IOC--IOC容器的23个实验(2)

    Spring--2.Spring之IOC--IOC容器的23个实验(1) 中的所有实验我都是在同一个工程中进行的,从第十个实验开始,我将新建一个新的工程开始实验. 目前导包还是跟第一个项目一致,bea ...

  6. Oozie任务调度框架详解及使用简介(一)

    摘要:个人最近一段时间一直在使用oozie,从刚开始的各种别扭到现在越来越觉得有意思的情况下,想整理一下关于oozie的认知,整理出来一个oozie系列,本来市面上关于oozie的资料就比较少,希望写 ...

  7. java架构之路(多线程)AQS之ReetrantLock显示锁的使用和底层源码解读

    说完了我们的synchronized,这次我们来说说我们的显示锁ReetrantLock. 上期回顾: 上次博客我们主要说了锁的分类,synchronized的使用,和synchronized隐式锁的 ...

  8. 源码分析Kafka 消息拉取流程

    目录 1.KafkaConsumer poll 详解 2.Fetcher 类详解 本节重点讨论 Kafka 的消息拉起流程. @(本节目录) 1.KafkaConsumer poll 详解 消息拉起主 ...

  9. Js字符串按数量分组

    代码: function group(ss,step) { var r = []; function doGroup(s) { if (!s) return; r.push(s.substr(0, s ...

  10. vue 项目路由跳转后显示不同的title

    1.在router/index.js的每个路由中配置title 2.在项目中运行命令 npm install vue-wechat-title --save 安装插件(在 package.json文件 ...