学编程,来源栈;先学习,再交钱
当前系列: C#语法 修改讲义
复习:正则表达式

事先准备两个字符串

string input = "17bang";//待匹配字符串
string pattern = "\\d";//正则表达式

另外,需要引入名称空间

using System.Text.RegularExpressions;


Regex

可以直接使用它的静态方法,比如:

  • 判断能否匹配:
    Console.WriteLine(Regex.IsMatch(input, pattern));
  • 将匹配内容进行替换:
    Console.WriteLine(Regex.Replace(input, pattern, "x"));
也可以new一个对象之后调用其实例方法:
Regex regex = new Regex(pattern);    //传入正则表达式
然后一样的调用:
Console.WriteLine(regex.Replace(input, "x"));
Console.WriteLine(regex.IsMatch(input));


Match对象

调用(静态/实例)Match()方法,返回的是一个封装了匹配结果的Match对象

Match result = Regex.Match(input, pattern);
Match result = new Regex(pattern).Match(input);

Match对象有一些简单方法:

Console.WriteLine(match.Success);
Console.WriteLine(match.Value);
Console.WriteLine(match.Index);
Console.WriteLine(match.NextMatch().Value);
Console.WriteLine(match.NextMatch().Index);


Matches()过滤

可以取出多个匹配结果,进行迭代。比如,找出能被3整除的数字。

先准备数据:

string input = "2022年6月8日";
string pattern = "\\d+";
利用Matches()方法,
MatchCollection matches = regex.Matches(input);
注意返回的是非泛型形式的MatchCollection,所以如果在foreach里使用var的话,编译时只会将其推导为object类型:

但是,F12转到定义,我们就会看到它实现的是:

public class MatchCollection : ICollection<Match>

即集合中元素实际上为Match类型。所以,

  • 要么在foreach循环体里面进行强转(不推荐)
    foreach (var item in matches)
    {
        if (Convert.ToInt32(((Match)item).Value) % 3 == 0)
  • 要么在foreach声明时就指明元素类型(推荐)
    foreach (Match item in regex.Matches(input)){
        if (Convert.ToInt32(item.Value)%3==0)
        {
            Console.WriteLine(item);


MatchEvaluator

上面的方法只能得到匹配结果,不能对原字符串进行操作(比如替换)。

所以,Regex还提供了一个Replace()方法的重载,可以传入一个MatchEvaluator(委托)

string result = Regex.Replace(input, pattern, (m) =>
{
    return Convert.ToInt32(m.Value) % 3 == 0 ?
        "xx" :
        m.Value;
});


group 

需求:找出下input中的年月日:(注意干扰项18-40)

string input = "源栈·一起帮,自2019-2-18成立以来,招收18-40岁的……";    //待匹配字符串

按我们之前学习的知识,我们可以首先利用正则表达式:

string pattern = @"(\d+)-(\d+)-(\d+)";     //注意圆括号

因为正则表达式中用圆括号进行了分组,接下来我们就可以:

GroupCollection groups = regex.Match(input).Groups;
foreach (Group item in groups)
{
    Console.WriteLine($"{item.Name}({item.Index}):{item.Value}");

演示:运行结果,说明:默认匹配结果是第一个group,name为0

命名group

如果我们要获取某一个分组内容的话,还可以使用下标:

Console.WriteLine(groups[1]);
@想一想@:这是什么语法?(复习:索引器)

F12转到定义(演示),这两个索引器,怎么回事?(复习:接口实现)

public Group this[int groupnum]
Group IList<Group>.this[int index]

@想一想@:但groups[1]的类型不是Group吗,为什么不是输出类名,而是类似于:

Console.WriteLine(groups[1].Value);

的效果?

另外,如果我们在正则表达式中设置了group的名字:

string pattern = @"(?<year>\d+)-(?<month>\d+)-(?<day>\d+)";

就可以在后续直接使用name:

Console.WriteLine(groups["year"].Value);

再次演示:foreach

替换

分组更大的作用是方便替换。比如需求变更为:讲日期格式从短横线格式变成年月日格式,即2019-2-18变2019年2月18日,可以简单的使用:

Console.WriteLine(Regex.Replace(input, pattern, "${1}年${2}月${3}日"));

其中${1}就代表第一个分组内容,其他依次类推。

还可以使用group名(如果定义了的话):

Regex.Replace(input, pattern, "${year}年${month}月${day}日")


作业

见:J&C:字符串:值类型?/ 池 / 常用方法 / StringBuilder / 正则

学习笔记
源栈学历
大多数人,都低估了编程学习的难度,而高估了自己的学习能力和毅力。

作业

觉得很 ,不要忘记分享哟!

任何问题,都可以直接加 QQ群:273534701

在当前系列 C#语法 中继续学习:

多快好省!前端后端,线上线下,名师精讲

  • 先学习,后付费;
  • 不满意,不要钱。
  • 编程培训班,我就选源栈

更多了解 加:

QQ群:273534701

答疑解惑,远程debug……

B站 源栈-小九 的直播间

写代码要保持微笑 (๑•̀ㅂ•́)و✧

公众号:源栈一起帮

二维码