主頁 > .NET開發 > 解讀C#中的正則運算式

解讀C#中的正則運算式

2020-09-24 05:11:22 .NET開發

本文摘自LTP.NET知識庫,

regexp規則類包含在System.Text.RegularExpressions.dll檔案中,在對應用軟體進行編譯時你必須參考這個檔案:

System.Text.RegularExpressions.dll

名字空間簡介

在名字空間中僅僅包含著6個類和一個定義,它們是:

Capture: 包含一次匹配的結果;

CaptureCollection: Capture的序列;

Group: 一次組記錄的結果,由Capture繼承而來;

Match: 一次運算式的匹配結果,由Group繼承而來;

MatchCollection: Match的一個序列;

MatchEvaluator: 執行替換操作時使用的代理;

Regex: 編譯后的運算式的實體,

Regex類中還包含一些靜態的方法

Escape: 對字串中的regex中的轉義符進行轉義;

IsMatch: 如果運算式在字串中匹配,該方法回傳一個布林值;

Match: 回傳Match的實體;

Matches: 回傳一系列的Match的方法;

Replace: 用替換字串替換匹配的運算式;

Split: 回傳一系列由運算式決定的字串;

Unescape:不對字串中的轉義字符轉義,

簡單匹配

先從使用Regex、Match類的簡單運算式開始學習,

Match m = Regex.Match("abracadabra", "(a|b|r)+");

例:

if (m.Success)...

如果想使用匹配的字串,可以把它轉換成一個字串:

Console.WriteLine("Match="+m.ToString());

輸出: Match=abra,

這就是匹配的字串,

字串的替換

簡單字串的替換非常直觀,

例如下面的陳述句:

string s = Regex.Replace("abracadabra", "abra", "zzzz");

它回傳字串zzzzcadzzzz,所有匹配的字串都被替換成了zzzzz,

現在我們來看一個比較復雜的字串替換的例子:

string s = Regex.Replace(" abra ", @"^\s*(.*?)\s*$", "$1");

這個陳述句回傳字串abra,其前導和后綴的空格都去掉了,

上面的模式對于洗掉任意字串中的前導和后續空格都非常有用,

在C#中,我們還經常使用字母字串,在一個字母字串中,編譯程式不把字符“ \” 作為轉義字符處理,在使用字符“\”指定轉義字符時,@"..."是非常有用的,

另外值得一提的是$1在字串替換方面的使用,它表明替換字串只能包含被替換的字串,

匹配引擎的細節

接下來通過一個組結構來理解一個稍微復雜的例子:

string text = "abracadabra1abracadabra2abracadabra3";    
string pat = @"    
  ????( # 第一個組的開始    
  ???? abra # 匹配字串abra    
  ???? ( # 第二個組的開始    
  ???? cad # 匹配字串cad    
  ???? )? # 第二個組結束(可選)    
  ????) # 第一個組結束    
  ????+ # 匹配一次或多次    
  ????"; 
   
  ??//利用x修飾符忽略注釋    
  ??Regex r = new Regex(pat, "x"); 
   
  ??//獲得組號碼的清單    
  ??int[] gnums = r.GetGroupNumbers(); 
   
  ??//首次匹配    
  ??Match m = r.Match(text); 
   
  ??while (m.Success)    
  ?? {    
  ??//從組1開始    
  ?? for (int i = 1; i < gnums.Length; i++) 
   
  ????{ 
   
  ????Group g = m.Group(gnums[i]); 
   
  ??//獲得這次匹配的組    
  ????Console.WriteLine("Group"+gnums[i]+"=["+g.ToString()+"]"); 
   
  ??//計算這個組的起始位置和長度    
  ????CaptureCollection cc = g.Captures; 
   
  ????for (int j = 0; j < cc.Count; j++) 
   
  ???? { 
   
  ???? Capture c = cc[j]; 
   
  ???? Console.WriteLine(" Capture" + j + "=["+c.ToString() 
   
  ?????? + "] Index=" + c.Index + " Length=" + c.Length); 
   
  ???? }    
  ????}    
  ??//下一個匹配    
  ?? m = m.NextMatch();    
  ?? }

這個例子的輸出如下所示:

Group1=[abra] 
   
  ??????Capture0=[abracad] Index=0 Length=7 
   
  ??????Capture1=[abra] Index=7 Length=4 
   
  ??Group2=[cad] 
   
  ??????Capture0=[cad] Index=4 Length=3 
   
  ??Group1=[abra] 
   
  ??????Capture0=[abracad] Index=12 Length=7 
   
  ??????Capture1=[abra] Index=19 Length=4 
   
  ??Group2=[cad] 
   
  ??????Capture0=[cad] Index=16 Length=3 
   
  ??Group1=[abra] 
   
  ??????Capture0=[abracad] Index=24 Length=7 
   
  ??????Capture1=[abra] Index=31 Length=4 
   
  ??Group2=[cad] 
   
  ??????Capture0=[cad] Index=28 Length=3

我們首先從考查字串pat開始,pat中包含有運算式,

第一個capture是從第一個圓括號開始的,然后運算式將匹配到一個abra,

第二個capture組從第二個圓括號開始,但第一個capture組還沒有結束,這意味著第一個組匹配的結果是abracad ,而第二個組的匹配結果僅僅是cad,

因此如果通過使用?符號而使cad成為一項可選的匹配,匹配的結果就可能是abra或abracad,

然后,第一個組就會結束,通過指定+符號要求運算式進行多次匹配,

現在我們來看看匹配程序中發生的情況,

首先,通過呼叫Regex的constructor方法建立運算式的一個實體,并在其中指定各種選項,

在這個例子中,由于在運算式中有注釋,因此選用了x選項,另外還使用了一些空格,

打開x選項,運算式將會忽略注釋和其中沒有轉義的空格,

然后,取得運算式中定義的組的編號的清單,

你當然可以顯性地使用這些編號,在這里使用的是編程的方法,

如果使用了命名的組,作為一種建立快速索引的途徑這種方法也十分有效,

接下來是完成第一次匹配,

通過一個回圈測驗當前的匹配是否成功,接下來是從group 1開始重復對組清單執行這一操作,

在這個例子中沒有使用group 0的原因是group 0是一個完全匹配的字串,如果要通過收集全部匹配的字串作為一個單一的字串,就會用到group 0了,

我們跟蹤每個group中的CaptureCollection,

通常情況下每次匹配、每個group中只能有一個capture,但本例中的Group1則有兩個capture:Capture0和Capture1,

如果你僅需要Group1的ToString,就會只得到abra,當然它也會與abracad匹配,

組中ToString的值就是其CaptureCollection中最后一個Capture的值,這正是我們所需要的,

如果你希望整個程序在匹配abra后結束,就應該從運算式中洗掉+符號,讓regex引擎知道我們只需要對運算式進行匹配,

基于程序和基于運算式方法的比較

一般情況下,使用正則運算式的用戶可以分為以下二大類:

第一類用戶盡量不使用正則運算式,而是使用程序來執行一些需要重復的操作;

第二類用戶則充分利用正則運算式處理引擎的功能和威力,而盡可能少地使用程序,

對于我們大多數用戶而言,最好的方案莫過于二者兼而用之了,

希望這篇文章能夠說明.NET語言中regexp類的作用以及它在性能和復雜性之間的優、劣點,

基于程序的模式

我們在編程中經常需要用到的一個功能是對字串中的一部分進行匹配或其他一些對字串處理,下面是一個對字串中的單詞進行匹配的例子:

string text = "the quick red fox jumped over the lazy brown dog."; 
System.Console.WriteLine("text=[" + text + "]"); 
string result = ""; 
string pattern = @"\w+|\W+"; 
foreach (Match m in Regex.Matches(text, pattern)) 
{ 
   
  ??// 取得匹配的字串    
  ?? string x = m.ToString(); 
   
  ??// 如果第一個字符是小寫    
  ?? if (char.IsLower(x[0])) 
   
  ??// 變成大寫    
  ??x = char.ToUpper(x[0]) + x.Substring(1, x.Length-1); 
   
  ??// 收集所有的字符    
  ?? result += x; 
 } 
   
System.Console.WriteLine("result=[" + result + "]");

正象上面的例子所示,我們使用了C#語言中的foreach陳述句處理每個匹配的字符,并完成相應的處理,在這個例子中,新創建了一個result字串,

這個例子的輸出所下所示:

text=[the quick red fox jumped over the lazy brown dog.] 
result=[The Quick Red Fox Jumped Over The Lazy Brown Dog.]

基于運算式的模式

完成上例中的功能的另一條途徑是通過一個MatchEvaluator,新的代碼如下所示:

static string CapText(Match m) 
   
  ????{ 
   
  ??//取得匹配的字串 
   
  ????string x = m.ToString(); 
   
  ??// 如果第一個字符是小寫 
   
  ????if (char.IsLower(x[0])) 
   
  ??// 轉換為大寫 
   
  ???? return char.ToUpper(x[0]) + x.Substring(1, x.Length-1); 
   
  ????return x; 
   
  ????} 
   
  ???? 
   
  ?? static void Main() 
   
  ????{ 
   
  ????string text = "the quick red fox jumped over the 
   
  ???? lazy brown dog."; 
   
  ????System.Console.WriteLine("text=[" + text + "]"); 
   
  ????string pattern = @"\w+"; 
   
  ????string result = Regex.Replace(text, pattern, 
   
  ?? new MatchEvaluator(Test.CapText)); 
   
  ????System.Console.WriteLine("result=[" + result + "]"); 
   
  ????}

同時需要注意的是,由于僅僅需要對單詞進行修改而無需對非單詞進行修改,這個模式顯得非常簡單,

本文來自木莊網路博客> 解讀C#中的正則運算式

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/116633.html

標籤:C#

上一篇:.Net Core 3.0 WebAPI && MySQL 8.0搭建詳情

下一篇:C#使用NLog記錄日志

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more