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

标签:C#,正则表达式
0
投稿

猜你喜欢

  • SpringBoot实现异步事件驱动的方法

    2023-11-01 07:48:54
  • 深入C#中get与set的详解

    2022-05-29 21:04:10
  • Java基于JDBC实现事务,银行转账及货物进出库功能示例

    2022-03-24 07:06:34
  • 详解从零开始---用C#制作扫雷游戏

    2022-06-14 13:33:12
  • 简单掌握Android Widget桌面小部件的创建步骤

    2021-12-07 01:48:35
  • Android实现检测手机多点触摸点数

    2021-11-17 00:57:32
  • SpringMVC Validator验证示例

    2021-08-19 14:33:30
  • C#使用log4net打日志

    2022-11-08 17:50:57
  • 有关于整体刷新和局部刷新frameset窗口

    2023-04-21 22:43:40
  • SpringBoot通过JSON传递请求参数的实例详解

    2023-11-26 22:59:24
  • Java8 用Lambda表达式给List集合排序的实现

    2023-02-05 17:27:09
  • Spring Boot自动配置的原理及@Conditional条件注解

    2021-08-31 21:14:11
  • Java Timezone类常见问题_动力节点Java学院整理

    2023-08-23 01:30:11
  • android实现歌词自动滚动效果

    2022-03-16 17:09:10
  • SpringCloud如何创建一个服务提供者provider

    2023-08-01 01:56:33
  • Java PDF 添加数字签名的实现方法

    2022-01-03 04:05:56
  • springmvc分层领域模型概念详解

    2021-09-07 01:21:51
  • Android抓取CSDN首页极客头条内容完整实例

    2023-06-09 17:01:16
  • Java编写Mapreduce程序过程浅析

    2023-02-26 02:53:20
  • Mybatis 开发注解快速入门

    2021-12-01 16:03:36
  • asp之家 软件编程 m.aspxhome.com