C# 正則進階

来源:https://www.cnblogs.com/gl1573/archive/2020/02/12/12298529.html

假設一個密碼要求長度大於 8 位,至少包含一個數字、一個小寫字母、一個大寫字母,如果用一條正則驗證? ...


.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

您的分享是我們最大的動力!

更多相關文章
  • 在前面幾篇文章的例子中也可以看到mybatis中輸入映射和輸出映射的身影,但是沒有系統的總結一下,這篇博客主要對這兩個東東做一個總結。我們知道mybatis中輸入映射和輸出映射可以是基本數據類型、hashmap或者pojo的包裝類型,這裡主要來總結一下pojo包裝類型的使用,因為這個在開發中比較常用 ...
  • 4.1 數組的相關概念和名詞(瞭解) 1、數組(array): 一組具有相同數據類型的數據的按照一定順序排列的集合。 把有限的幾個相同類型的變數使用一個名稱來進行統一管理。 2、數組名: (1)這個數組名,代表的是一組數 (2)這個數組名中存儲的整個數組的“首地址” 3、下標(index): 我們使 ...
  • 由於Api的介面需要返回多語言,因此參考了網上很多篇文章,,有些文章寫的太過於理論,看起來比較費勁,今天下午搞了一個下午,總結了一下經驗,, 做這個功能時,主要參考了兩篇文章: https://blog.johnwu.cc/article/ironman-day21-asp-net-core-loc ...
  • 在 寫xaml的使用遇到了一些特殊字元,這裡記錄一下特殊字元轉義。 這些特殊字元遵循用於編碼的萬維網聯合會(W3C) XML 標準。 下表顯示這組特殊字元的編碼語法: 字元語法描述 < &lt; 小於符號。 > &gt; 大於符號。 & &amp; & 符號。 " &quot; 雙引號。 參見: h ...
  • 樣式提供了重用一組屬性設置的實用方法。它們為幫助構建一致的、組織良好的界面邁出了重要的第一步——但是它們也是有許多限制。 問題是在典型的應用程式中,屬性設置僅是用戶界面基礎結構的一小部分。甚至最基本的程式通常也需要大量的用戶界面代碼,這些代碼與應用程式的功能無關。在許多程式中,用於用戶界面任務的代碼 ...
  • static void Main(string[] args) { InsertionSortDemo(); Console.ReadLine(); } static void InsertionSortDemo() { Random rnd = new Random(); int[] arr = ...
  • 長鏈接發送request/response時, 絕大部分包都是小包, 而每個小包都要消耗一個IP包, 成本大約是20-30us, 普通千兆網卡的pps大約是60Wpps, 所以想要提高長鏈接密集IO的應用性能, 需要做包的合併, 也稱為了scatter/gather io或者vector io. 在 ...
  • 如何重構我們以前寫的垃圾代碼——觀察者模式 首先來看下 GoF 對觀察者模式的定義: 多個對象間存在一對多關係,當一個對象發生改變時,把這種改變通知給其他多個對象,從而影響其他對象的行為 就是說當一個對象要發生變化時,要通知其他多個對象同時要發生相應的變化的行為。 從這句定義上來看,重點在於兩個“對 ...
一周排行
  • 上一篇文章(https://www.cnblogs.com/meowv/p/12943699.html)完成了項目的全局異常處理和日誌記錄。 在日誌記錄中使用的靜態方法有人指出寫法不是很優雅,遂優化一下上一篇中日誌記錄的方法,具體操作如下: 在.ToolKits層中新建擴展方法Log4NetExte ...
  • 先安裝幾個包 獲取地址如下https://www.nuget.org/packages/QRCoder/https://www.nuget.org/packages/SixLabors.Fonts/https://www.nuget.org/packages/SixLabors.ImageSharp ...
  • 0. 前言 前一篇我們詳細的介紹了SqlSugar的增刪改查,那些已經滿足我們在日常工程開發中的使用了。但是還有一點點在開發中並不常用,但是卻非常有用的方法。接下來讓我們一起來看看還有哪些有意思的內容。 1. 不同尋常的查詢 之前介紹了針對單個表的查詢,同樣也是相對簡單的查詢模式。雖然開發完全夠用, ...
  • 最新.net core 圖片合併生成二維碼合成圖片 圖片添加文字 先安裝幾個包 獲取地址如下 https://www.nuget.org/packages/QRCoder/ https://www.nuget.org/packages/SixLabors.Fonts/ https://www.nug ...
  • 前言 之前我寫過一篇關於 Blazor WebAssembly 的文章瀏覽器中的 .Net Core —— Blazor WebAssembly 初體驗,如今已經更新到 RC-1,與預覽版有著較大的差異,為此補充這篇文章。 正文 與預覽版的主要差異 1、這次的候選版修改了大部分包名和命名空間,因此無 ...
  • 藍牙設置相關界面,以下是通過C#方式打開的幾個方式,記錄一下 藍牙設置界面 1.控制面板命令bthprops.cpl 可以用控制面板 control+bthprops.cpl,也可以直接bthprops.cpl。更多的命令見:所有運行命令指令大全、CMD & CPL:快捷系統命令和控制面板命令 bt ...
  • 一:背景 1. 講故事 去年阿裡聚石塔上的所有isv簡訊通道全部對接阿裡通信,我們就做了對接改造,使用阿裡提供的.net sdk。 網址:https://help.aliyun.com/document_detail/114480.html 同事當時使用的是ons-.net v1.1.3版本,程式上 ...
  • 一.相關介紹 Dockerfile:關於Dockerfile的使用說明,我在文章《讓.NetCore程式跑在任何有docker的地方》中有說到,這裡不在贅述,需要的可以先看下,本文主要介紹Jenkinsfile結合dockerfile配合使用,自動構建.NetCore應用程式。 Jenkinsfil ...
  • 當用戶嚮應用程式發出請求時,伺服器將解析該請求,生成響應,然後將結果發送給客戶端。用戶可能會在伺服器處理請求的時候中止請求。就比如說用戶跳轉到另一個頁面中獲取說關閉頁面。在這種情況下,我們希望停止所有正在進行的工作,以浪費不必要的資源。例如我們可能要取消SQL請求、http調用請求、CPU密集型操作 ...
  • 在.NET中,我們可以通過Task.WhenAll用來等待多個任務。任務完成之後,我們可以使用await等待他們來獲取結果。 Task<int> task1 = Task.Run(() => 1); Task<string> task2 = Task.Run(() => "hello"); awai ...