C# 正則進階

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

假設一個密碼要求長度大於 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

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

-Advertisement-
Play Games
更多相關文章
  • 在前面幾篇文章的例子中也可以看到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 對觀察者模式的定義: 多個對象間存在一對多關係,當一個對象發生改變時,把這種改變通知給其他多個對象,從而影響其他對象的行為 就是說當一個對象要發生變化時,要通知其他多個對象同時要發生相應的變化的行為。 從這句定義上來看,重點在於兩個“對 ...
一周排行
    -Advertisement-
    Play Games
  • Dapr Outbox 是1.12中的功能。 本文只介紹Dapr Outbox 執行流程,Dapr Outbox基本用法請閱讀官方文檔 。本文中appID=order-processor,topic=orders 本文前提知識:熟悉Dapr狀態管理、Dapr發佈訂閱和Outbox 模式。 Outbo ...
  • 引言 在前幾章我們深度講解了單元測試和集成測試的基礎知識,這一章我們來講解一下代碼覆蓋率,代碼覆蓋率是單元測試運行的度量值,覆蓋率通常以百分比表示,用於衡量代碼被測試覆蓋的程度,幫助開發人員評估測試用例的質量和代碼的健壯性。常見的覆蓋率包括語句覆蓋率(Line Coverage)、分支覆蓋率(Bra ...
  • 前言 本文介紹瞭如何使用S7.NET庫實現對西門子PLC DB塊數據的讀寫,記錄了使用電腦模擬,模擬PLC,自至完成測試的詳細流程,並重點介紹了在這個過程中的易錯點,供參考。 用到的軟體: 1.Windows環境下鏈路層網路訪問的行業標準工具(WinPcap_4_1_3.exe)下載鏈接:http ...
  • 從依賴倒置原則(Dependency Inversion Principle, DIP)到控制反轉(Inversion of Control, IoC)再到依賴註入(Dependency Injection, DI)的演進過程,我們可以理解為一種逐步抽象和解耦的設計思想。這種思想在C#等面向對象的編 ...
  • 關於Python中的私有屬性和私有方法 Python對於類的成員沒有嚴格的訪問控制限制,這與其他面相對對象語言有區別。關於私有屬性和私有方法,有如下要點: 1、通常我們約定,兩個下劃線開頭的屬性是私有的(private)。其他為公共的(public); 2、類內部可以訪問私有屬性(方法); 3、類外 ...
  • C++ 訪問說明符 訪問說明符是 C++ 中控制類成員(屬性和方法)可訪問性的關鍵字。它們用於封裝類數據並保護其免受意外修改或濫用。 三種訪問說明符: public:允許從類外部的任何地方訪問成員。 private:僅允許在類內部訪問成員。 protected:允許在類內部及其派生類中訪問成員。 示 ...
  • 寫這個隨筆說一下C++的static_cast和dynamic_cast用在子類與父類的指針轉換時的一些事宜。首先,【static_cast,dynamic_cast】【父類指針,子類指針】,兩兩一組,共有4種組合:用 static_cast 父類轉子類、用 static_cast 子類轉父類、使用 ...
  • /******************************************************************************************************** * * * 設計雙向鏈表的介面 * * * * Copyright (c) 2023-2 ...
  • 相信接觸過spring做開發的小伙伴們一定使用過@ComponentScan註解 @ComponentScan("com.wangm.lifecycle") public class AppConfig { } @ComponentScan指定basePackage,將包下的類按照一定規則註冊成Be ...
  • 操作系統 :CentOS 7.6_x64 opensips版本: 2.4.9 python版本:2.7.5 python作為腳本語言,使用起來很方便,查了下opensips的文檔,支持使用python腳本寫邏輯代碼。今天整理下CentOS7環境下opensips2.4.9的python模塊筆記及使用 ...