引言

在不同语言中虽正则表达式一样,但应用函数还是有所区别,在c#语言中使用Regex。

可以通过以下两种方式之一使用正则表达式引擎:

  • 通过调用 Regex 类的静态方法。 方法参数包含输入字符串和正则表达式模式。 正则表达式引擎会缓存静态方法调用中使用的正则表达式,这样一来,重复调用使用同一正则表达式的静态正则表达式方法将提供相对良好的性能。
  • 通过实例化 Regex 对象,采用的方式是将一个正则表达式传递给类构造函数。 在此情况下,Regex 对象是不可变的(只读),它表示一个与单个正则表达式紧密耦合的正则表达式引擎。 由于未对 Regex 实例使用的正则表达式进行缓存,因此不应使用同一正则表达式实例化 Regex 对象多次。
  • 可以调用 Regex 类的方法来执行下列操作:

    确定字符串是否与正则表达式模式匹配。(ismatch)

    提取单个匹配项或第一个匹配项。(match)

    提取所有匹配项。(matches)

    替换匹配的子字符串。(replace)

    将单个字符串拆分成一个字符串数组。(replace)

    匹配正则表达式模式

    如果字符串与模式匹配,则 Regex.IsMatch 方法返回 true;如果字符串与模式不匹配,则此方法返回 false。
string[] values = { "111-22-3333", "111-2-3333"};
string pattern = @"^\d{3}-\d{2}-\d{4}$";
foreach (string value in values)
{
if (Regex.IsMatch(value, pattern))
Console.WriteLine("{0} is a valid SSN.", value);
else
Console.WriteLine("{0}: Invalid", value);
}

111-22-3333 is a valid SSN.

111-2-3333: Invalid

IsMatch()这个函数验证指定的字符串是否匹配指定的正则表达式,但是注意:

默认情况下,如果在整个字符串中只要有一部分匹配给定的字符串则返回true

一般情况下,当调用IsMatch()函数的时候都希望是完全匹配,所以在写正则的时候两边都要加^与$。

正则表达式重点是在总结字符规律,注意元字符的使用还有转义字符。

提取单个匹配项或第一个匹配项

Regex.Match 方法返回一个 Match 对象,该对象包含有关与正则表达式模式匹配的第一个子字符串的信息。

string msg = "大家好呀,hello,2010年10月10日是个好日子。恩,9494";
//逐个提取
//字符串提取Match()和Matches()
//提取第一个匹配的字符串,只提取一个。
Match match = Regex.Match(msg, @"\d+", RegexOptions.ECMAScript);
Console.WriteLine(match.Value);
Console.ReadLine();

只输出2010,如果想输出全部数字,用matches。

提取所有匹配项

Regex.Matches 方法返回一个 MatchCollection 对象,该对象包含有关正则表达式引擎在输入字符串中找到的所有匹配项的信息。

 string msg = "大夫,我咳嗽得很重。”     大夫:“你多大年记?”     患者:“七十五岁。”     大夫:“二十岁咳嗽吗”患者:“不咳嗽。?";
MatchCollection matches = Regex.Matches(msg, "咳嗽");
foreach (Match item in matches)
{
Console.WriteLine(item.Index);
}
Console.WriteLine("一共出现了{0}", matches.Count);

输出3,返回的是一个集合,然后在里面逐一提取。

在捕获内容时,还有捕获组的概念,就是用括号进行表示。先写一个能满足整个字符串的正则表达式,然后在正则表达式中用括号将那些你想要提取的内容括起来,这样就可以提取你想要的组了。

string msg = "June26,1951    ";
Match match = Regex.Match(msg, @"^([a-zA-Z]+)\s*(\d{1,2})\s*,\s*(\d{4})\s*$");
Console.WriteLine(match.Groups[1].Value);
Console.WriteLine(match.Groups[2].Value);
Console.WriteLine(match.Groups[3].Value);

这样就能在全部匹配的情况下,分别获取了june 26 1951

贪婪模式

正则表达式会尽可能多的找到匹配,这就是正则表达式的贪婪模式。

终止贪婪模式: ? 具有终止贪婪模式的功能。当?出现在了另外一个限定符后的时候,表示终止贪婪模式。终止贪婪模式,表示,尽可能少的去匹配,则只匹配一个。

 string msg = "1111。11。111。111111。";
//结果是全部字符串
Match match = Regex.Match(msg, "(.+)(。)");
//结果是1111。如果没有。就是1,匹配时他要尽可能匹配。
Match match = Regex.Match(msg, ".+?。");
Console.WriteLine(match.Value);

替换匹配的子字符串

Regex.Replace 方法会将与正则表达式模式匹配的每个子字符串替换为指定的字符串或正则表达式模式,并返回进行了替换的整个输入字符串。

string msg = "我的生日是05/21/2010耶我的生日是03/11/2000耶我的生日是05/21/2010耶我的生日是05/21/2010耶";
//在替换的方法中,使用提取组。 注意在引用分组的时候是使用 $1、$2、.....
msg = Regex.Replace(msg, @"(\d{2})/(\d{2})/(\d{4})", "$3-$1-$2");

反向引用

捕获组捕获到的内容,不仅可以在正则表达式外部通过程序进行引用,也可以在正则表达式内部进行引用,这种引用方式就是反向引用。反向引用的作用通常是用来查找或限定重复、查找或限定指定标识配对出现等等。在正则表达式内部,要引用内部的分组,则使用\1 \2 \3 \4 等来引用分组。

对于普通捕获组的反向引用,是通过捕获组的编号来实现的。([ab])\10

这里的“\10”会被解析成第10个捕获组的反向引用。

string msg = "你你你好好好好好好妈妈妈妈妈妈妈妈";
msg = Regex.Replace(msg, @"(.)\1+", "$1");

这个输出结果是“你好妈”,正则表达式表示含义时,找到一个字符以他未引用出现多次的进行替换,替换为反向引用的内容。

上述代码中使用了提取组的概念。

提取组:先写一个能满足整个字符串的正则表达式,然后在正则表达式 中用括号将那些想要的内容进行提取内容括起来。

小括号从左边开始数,第一个小括号就是第一组,第二个小括号就是第二组,

只数左边的括号。如没有,直接返回null。

在正则表达式应用中就是匹配、提取、替换,当然还有这几个应用的组合,要灵活应用。

c#基础语言编程-正则表达式应用的更多相关文章

  1. c#基础语言编程-正则表达式基础

    引言 正则表达式是一种用高度抽象的字符串来描述字符串特征,进而实现对字符串的匹配.提取.替换等等.正则表达式(以下简称正则,Regex)通常不独立存在,各种编程语言和工具作为宿主语言提供对正则的支持, ...

  2. c#基础语言编程-程序集和反射

    程序集 什么是程序集? 1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合. 2.程序集是组件复用,以及实施安全策略和版本策略的最小单位. 3.程序集是包含一个或者多个 ...

  3. c#基础语言编程-文件流操作

    引言 在System.IO 命名空间下提供了一系列的类,我们可以通过相应的类进行文件.目录.数据流的操作. 1.File类:提供用于创建.复制.删除.移动和打开文件的静态方法.File类 2.File ...

  4. c#基础语言编程-编码

    字符编码是计算机技术的基础理论,其字符编码有ASCII码.UTF-8.还有就是GB2312,当然这是在中国常用的. 1.ASCII码 在计算机内部所有的信息都是以二进制字符进行存储.用每个二进制位中的 ...

  5. c#基础语言编程-Path和Directory

    引言 在程序常会对文件操作,在对文件操作中需要对文件路径的进行定位,在.Net中针对寻找文件提供两个静态类以供调用,Path和Directory. Path类 来自命名空间SYstem.IO,Path ...

  6. c#基础语言编程-装箱和拆箱

    引言 为什么有装箱和拆箱,两者起到什么作用?NET的所有类型都是由基类System.Object继承过来的,包括最常用的基础类型:int, byte, short,bool等等,就是说所有的事物都是对 ...

  7. c#基础语言编程-多态

    语言中的多态性是为了使程序有扩展性,为实现多态性,在程序中体现为接口.抽象类.父类.具体类. 接口就是一种规范,解决了多重继承的问题,类似一种规范,告诉我要做什么,具有什么能力,在接口中定义写行为属性 ...

  8. c#基础语言编程-序列化

    引言 程序员在编写应用程序的时候往往要将程序的某些数据存储在内存中,然后将其写入某个文件或是将它传输到网络中的另一台计算机上以实现通讯.这个将程序数据转化成能被存储并传输的格式的过程被称为" ...

  9. c#基础语言编程-集合

    引言 在c#常用的集合分为非泛型集合和泛型集合. 非泛型集合的类和接口位于System.Collections命名空间.这些接口和类定义各种对象(如列表.队列.位数组.哈希表和字典)的集合. 泛型集合 ...

随机推荐

  1. 自定义QToolButton

    最近做界面需要添加很多工具栏按钮,所以自己定义了一个Button 直接上代码 SettingButton.cpp//设置Button的一些参数 #include "SettingButton ...

  2. js 中的流程控制-循环(for)语句

    for语句: <script> /* for(exp1;exp2;exp3){ 循环体; } exp1:无条件的执行第一个表达式 exp2:判断是否能执行循环体的条伯 exp3:做增量的操 ...

  3. Quartz1.8.5例子(二)

    /* * Copyright 2005 - 2009 Terracotta, Inc. * * Licensed under the Apache License, Version 2.0 (the ...

  4. Delphi中快捷键的使用

    CTRL+SHIFT+↑(↓) 在过程.函数.事件内部, 可跳跃到相应的过程.函数.事件的定义(在INTERFACE和IMPLEMENTATION之间来回切换)CTRL+J (弹出DELPHI语句提示 ...

  5. Test for open live write

    this is test document. this is test document. this is test document. this is test document. this is ...

  6. iOS程序开发引用的第三方库之间出现duplicate symbol时的处理方法

    iOS程序集成的第三方库过多时,很容易出现某几个库同时用到了一样的函数库,也就是在你的程序link时会提示duplicate symbol,而重复的符号又不是由你自己程序的代码造成的,也就说没法通过直 ...

  7. spoj 3885

    简单的博弈题,用dp解: 每个人只能拿1,l,k个硬币: dp[i][j]表示第j个人拿是否能拿第i枚硬币: 代码: #include<cstdio> #define maxn 10000 ...

  8. hibernate异常:Could not determine type for: java.util.Set

    根本原因:我实体类中的类型是raw,没法直接实例化的类型.private List<String> rightChoices;private Set<String> multi ...

  9. Lua常用的数据结构表示

    1.矩阵 Lua中有两种表示矩阵的方法,一是“数组的数组”.也就是说,table的每个元素是另一个table.例如,可以使用下面代码创建一个n行m列的矩阵:mt = {}          -- cr ...

  10. Android网络框架Volley(实战篇)

      之前讲了ym—— Android网络框架Volley(体验篇),大家应该了解了volley的使用,接下来我们要看看如何把volley使用到实战项目里面,我们先考虑下一些问题: 从上一篇来看 mQu ...