C# 正则表达式进阶
作者:丹枫无迹 发布时间:2022-12-26 01:56:32
.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
来源:https://www.cnblogs.com/gl1573/p/12298529.html


猜你喜欢
- 实现效果图:下面是具体代码,可直接复制:package com.lcw.rabbit.widget;import android.anima
- 本文实例为大家分享了Java实现人机猜拳游戏的具体代码,供大家参考,具体内容如下实现:User类public class User { pr
- 在构造函数里加上以下代码:this.DoubleBuffered = true;//设置本窗体SetStyle(ControlStyles.
- 废话不多说了,直接给大家贴代码了,具体代码如所示:/** * get方法的文件下载 * <p> &n
- Java Comparable 和 Comparator 的详解及区别Java 中为我们提供了两种比较机制:Comparable 和 Com
- 首先写个单例:public class SingleDemo { private static SingleDemo s =
- 今天在用rsa界面服务端的数据时,碰到了部分乱码的问题,虽然能解密出正确的数据但是前面会多一堆乱码.一开始以为是编码的问题,可是全都设置成了
- 转发和重定向相同点都是web开发中资源跳转的方式。不同点转发:是服务器内部的跳转,浏览器的地址栏不会发生变化。从一个页面到另一个页面的跳转还
- 传感器简单的介绍一下传感器: 就是设备用来感知周边环境变化的硬件。Android中的传感器包含在传感器框架中,属于android.hardw
- 在上节使用了H2之后感觉很爽,很轻便,正好有个项目要求简单,最好不适用外部数据库,于是就想着把H2数据库集成进来,这个系统已经存在了一个Or
- C# using 三种使用方式介绍1.using指令。using + 命名空间名字,这样可以在程序中直接用命令空间中的类型,而不必指定类型的
- (注意:本文基于JDK1.8)前言元素在存储到内存中,当我们需要使用在内存中存储的元素,这就涉及到在内存中查找元素,今天一起学习Vector
- 本文实例讲述了Java采用循环链表结构求解约瑟夫问题的方法。分享给大家供大家参考。具体分析如下:这是第一次java考试的试题,对于没看过链表
- 本文实例为大家分享了如何使用ItemTouchHelper实现侧滑删除和拖拽的具体代码,供大家参考,具体内容如下1. 定义一个简单bean类
- 可以静态绑定数据源,这样就自动为DataGridView控件添加 相应的行。假如需要动态为DataGridView控件添加新行,方法有很多种
- 在笔试编程过程中,关于数据的读取如果迷迷糊糊,那后来的编程即使想法很对,实现很好,也是徒劳,于是在这里认真总结了Java Scanner 类
- 本文实例为大家分享了java代码统计小程序,供大家参考,具体内容如下可以测试每周你的工作量package rexExp;import jav
- 悲观锁和乐观锁是面试高频问题之一,本文将对悲观锁和乐观锁简单的进行一个介绍。悲观锁(Pessimistic Locking)悲观锁在并发环境
- spring配置不扫描service层原因我将contoller给springmvc进行扫描,然后其余所有交给spring扫描然后发现ser
- 我们在使用C# 语言的Assembly.Load 来加载托管程序集并使用反射功能时,一般需要先通过Assembly.Load()