正則表達式與C++

轉自個人博客

1. 概述

1.1 正則表達式概述

正則表達式(Regular Expressions,簡稱 regex)是用于匹配文本模式的一種特殊字符序列,其可以用一系列字符來表示出不同文本的對應模式。正則表達式的應用范圍十分廣泛,包括驗證文本格式、判斷字符種類、解析文本信息、轉換目標文本、遍歷搜索文本、符號化文本等。

一般在文件搜索、瀏覽器搜索時都可以使用正則表達式來表達某一種想要的文本格式,在C++等編程語言中也是一樣,靈活正當地使用正則表達式可以很有效地提高代碼的可讀性和簡潔性。

另外要注意的是,隨著時間的推移,正則表達式的語法也在擴充升級,而C++對以下幾種語法均有著很好的支持,其中最主要的掌握ECMAScript就好:

  • ECMAScript:基于ECMAScript標準的語法。JavaScript、ActionScript和Jscript等語言都使用該標準。
  • basic:基本的POSIX語法。
  • extended:拓展的POSIX語法。
  • awk:POSIX awk實用工具使用的語法。
  • grep:POSIX grep實用工具使用的語法。
  • egrep:用逗號分隔的POSIX egrep語法。

1.2 C++中使用正則表達式

在 C++11 之前,C++ 并未內置正則表達式庫,不能直接使用正則表達式。如果開發者想要使用正則表達式對文本作快捷操作,那么就需要依賴第三方庫如 PCRE (Perl Compatible Regular Expressions) 或使用 Boost庫中的 Boost.Regex。而在 C++11 中,C++ 標準庫引入了<regex> 頭文件,這樣在C++中使用正則表達式就不需要鏈接導入第三方庫了。

示例:

#include <iostream>
#include <regex>
using namespace std;int main(){string text = "The number is 42";regex number_pattern("\\d+"); // 建立匹配模式,查找字符串中是否有數字if(regex_search(text, number_pattern)){cout << "Found a number!" << endl;}
}

2. 正則表達式的語法規則

正則表達式會用到的特殊字符為:^ $ \ . * + ? () [] {} |

每個字符的含義和用處將在下面逐步介紹。

2.1 單字符匹配

除了正則表達式會用到的特殊字符外,單個字符(包括大小寫字母、數字、其他字符等)就匹配指定的字符,比如:a 匹配字符 a

如果要匹配特殊字符,則需要使用特殊字符中的轉義字符\,比如:\^ 匹配字符 ^

對于需要匹配的文本中有未指定字符,就可以使用通配符.(點,英文句號)。通配符可以匹配任意單個字符,一般用在有部分不確定字符的情況下,比如a.c可以匹配到abca1c等一系列文本。只使用單個通配符就表示只匹配總長度為1的文本。

如果指定匹配任意數字或任意字母等非全部的情況時,可以使用字符類來指定一個范圍的字符,見下一小節。

2.2 字符類

  1. 預定義字符類

    是正則表達式內定的用于表示一類字符的情況,用于匹配單一字符

    • \\d:匹配任何數字字符(0-9)。
    • \\D:匹配任何數字字符。
    • \\w:匹配任何字母、數字或下劃線(A-Z、a-z、0-9 和 _)。
    • \\W:匹配任何字母、數字或下劃線的字符。
    • \\s:匹配任意空白字符(如空格、制表符、換行符等)。
    • \\S:匹配任何空白字符。
  2. 自定義字符集:

    正則表達式支持使用[]來自定義字符集,用于匹配單一字符,比如:[abc] 匹配字符abc

    使用**-**來指定字典順序的前后范圍,比如:[0-9] 匹配任意數字;[a-z] 匹配任意小寫字母;[A-Za-z] 匹配任意字母

  3. 反向字符類(排除指定字符

    在字符類 [] 中使用 ^ 作為第一個字符(緊跟‘[’之后才會生效),表示匹配不在該集合中的字符。示例如下

    • [^a-z]:匹配非小寫字母的任意字符
    • [^0-9]:匹配非數字的任意字符
    • [^aeiou]:匹配非元音字母的任意字符
    // 組合使用示例:匹配不含字母但必須包含數字的字符串
    std::regex no_letters_but_digits(R"(^[^A-Za-z]*[0-9]+[^A-Za-z]*$)");
    

2.3 重復字符匹配

在正則表達式中,特殊字符*+?被稱為量詞,用于匹配某個字符是否多次重復出現的情況。

  1. *(星號)

    表示出現零次或多次。用于匹配此符號前一個字符零次或多次,比如:a* 可以匹配到 空字符串aaaaaa 等。

  2. +(加號)

    表示出現一次或多次。用于匹配此符號前一個字符一次或多次,比如:a+可以匹配到aaaaaa` 等,但不會匹配空字符串

  3. ?(問號)

    表示出現零次或一次。用于匹配此符號前一個字符零次或一次,比如:a? 可以匹配到 空字符串或者 a

除此之外,還可以使用**{}**來指定出現次數的方位,格式為{min, max},即匹配此符號前一個字符至少min次,至多max次,可省略其中的,和后一個max數值:

  1. {n}

    用于匹配此符號前一個字符正好n次,比如:a{3} 只能匹配到aaa

  2. {min, }

    用于匹配此符號前一個字符至少min次,比如:a{3, } 可以匹配到aaaaaaaaaaaa等。

  3. {min, max}

    用于匹配此符號前一個字符至少min次,至多max次,比如:a{3, 5} 只能匹配到aaaaaaaaaaaa

2.4 邊界匹配

在正則表達式中,可以單獨指定匹配文本的開頭或結尾。分別使用**錨點^來指定開頭,使用錨點$**來指定結尾

  1. ^

    將這個符號放在文本首位,表明文本在此開頭。用于匹配字符串的開頭,比如:正則表達式^abc匹配以abc開頭的任意文本abc1abcd

  2. $

    將這個符號放在文本末尾,表明文本在此結尾。用于匹配字符串的結尾,比如:正則表達式abc$匹配以abc結尾的任意文本1abcdabc

錨點還可以混合使用,同時指定文本的開頭和結尾,比如:^abc$ 將只匹配字符串abc。還可以更復雜的混合使用,比如:^abc.*123$ 就可以匹配以abc開頭和123結尾的任意文本了。

錨點除了這兩個最常用的,還有很多指定更多特殊情況的,比如以下四種:

  1. \b

    用于匹配文本中指定的字母字符串(單詞)有邊界的情況。有\b代表必須有邊界,邊界是指無任意字符,當然可以是空格。

    比如:正則表達式 \babc 會匹配abc前面有邊界的情況,如xyz abc(abc前面有空格作邊界,無其他字符相連)、abcdef(abc前面無其他字符相連,后面不用管),而不能匹配abclabc;正則表達式 \babc\b 會匹配abc前后有邊界的情況,如abcxyz abc nnn,但不會匹配 111abcabcddd.

  2. \B

    \b的情況相反,用于匹配文本中指定的字母字符串(單詞邊界的情況。比如:正則表達式 \Babc 會匹配xabc(abc前面無邊界) ,但不會匹配abc

  3. \A

    用于匹配字符串的絕對開頭,與 ^ 的行為相似,但是 ^ 在多行模式下可能匹配每行的開頭,而 \A 始終匹配整個字符串的開頭。比如:\Aabc 只會匹配以 “abc” 開頭的字符串。

  4. \Z

    用于匹配字符串的絕對結尾,與 $ 的行為相似,但是 $ 在多行模式下可能匹配每行的結尾,而 \Z 始終匹配整個字符串的結尾。比如:\Z123 只會匹配以 123 結尾的字符串。

2.5 分組和選擇

正則表達式通過 () 可以將多個字符組合為一個組,可以對一個組的字符進行統一操作,比如:(ab)+ 可以匹配 abababababab 等。

正則表達式使用 | 表示選擇,可以理解為邏輯中的或,比如: (a|b) 表示匹配字符 ab

3. C++<regex>標準庫的基本使用

<regex>類是C++11引入的標準庫,需要包含頭文件#include <regex>,并使用命名空間std

官方中文文檔點這里傳送。

3.1 常用類和方法

  • std::regex: 表示一個正則表達式。它提供了存儲和操作正則表達式的能力。
  • std::smatch: 用于存儲 std::regex_match 函數的結果。這是一個用于匹配字符串的結果類型,通常使用于 std::string
  • std::cmatch: 與 std::smatch 類似,但用于處理 C 風格字符串(C-strings)。
  • std::regex_search: 用于在字符串中搜索與正則表達式匹配的部分。
  • std::regex_match: 用于檢查一個字符串是否完全匹配給定的正則表達式。
  • std::regex_replace: 用于替換字符串中與正則表達式匹配的部分。

3.2 創建正則表達式

使用std::regex類來聲明一個正則表達式的匹配模式

示例:

/// 聲明一個正則表達式,用于之后匹配一個或多個小寫字母  
std::regex pattern("[a-z]+");
/// 只禁止輸入_,其他字符不受影響
std::regex no_underscore(R"(^[^_]*$)");

注意:C++中可以通過對字符串使用**R"( )"**修飾來告訴編譯器保持字符串原樣,不處理轉義字符。前面說過,使用特殊字符需要使用\進行雙重轉義。

而這一般會用在正則表達式、文件路徑、JSON/XML數據等,普通字符串一般沒必要使用。

std::regex re("\\d+");  // 普通字符串:雙重轉義后,實際傳遞的正則是 "\d+"
std::regex re(R"(\d+)"); // 原始字符串:直接傳遞正則 "\d+"

3.3 匹配

使用**std::regex_match()來檢查整個字符串**是否完全匹配正則表達式。

第一個參數為目標字符串,第二個參數為指定正則表達式。匹配返回true,否則返回false。

示例:

std::string str = "hello";  
std::regex pattern("hello");  if (std::regex_match(str, pattern)) {  std::cout << "完整匹配成功!" << std::endl;  
} else {  std::cout << "不匹配。" << std::endl;  
}  

使用**std::regex_search()**查找字符串中是否存在與模式匹配的子字符串。

第一個參數為目標字符串,第二個參數為指定正則表達式。匹配返回true,否則返回false。

std::string str = "hello world";  
std::regex pattern("world");  if (std::regex_search(str, pattern)) {  std::cout << "找到匹配的部分!" << std::endl;  
} else {  std::cout << "未找到匹配。" << std::endl;  
}  

3.4 捕獲組

在正則表達式中用括號()包圍一段模式來捕獲文本中符合格式的子字符串,被稱為捕獲組。當正則表達式包含捕獲組時,可以通過 std::smatchstd::cmatch 來保存匹配的結果。且要注意在聲明正則表達式時使用**關鍵字R**來激活捕獲組。

std::smatchstd::cmatch 對象放在std::regex_match()第二個參數。

示例:

std::string str = "2023-10-08";  
std::regex pattern(R"(\d{4})-(\d{2})-(\d{2})"); // 分別捕獲年、月、日格式  /// 創建 smatch 對象以保存匹配結果 
std::smatch match;  
if (std::regex_match(str, match, pattern)) {  std::cout << "年: " << match[1] << ", 月: " << match[2] << ", 日: " << match[3] << std::endl;  
}  

3.5 替換

使用 std::regex_replace() 替換匹配部分。

第一個參數為目標字符串,第二個參數為指定正則表達式,第三個參數為替換的字符串。替換成功后返回替換后的字符串,否則返回原字符串。

示例:

std::string str = "I love cats and cats are great.";  
std::regex pattern("cats");  
std::string replaced = std::regex_replace(str, pattern, "dogs");  std::cout << "替換后的字符串: " << replaced << std::endl;  

3.6 指定正則選項

<regex>允許在創建 std::regex對象時,通過第二個參數指定一些正則選項,使用std::regex_constants 命名空間中的常量來指定選項。

  • std::regex_constants::icase:忽略大小寫

    在匹配時,忽略字符的大小寫。

  • std::regex_constants::multiline:多行匹配

    在多行字符串中,^$ 匹配每行的開始和結束,而不僅僅是整段字符串的開始和結束。

  • std::regex_constants::dotall:點號匹配換行符

    . 匹配的任意字符中增加換行符。

  • std::regex_constants::ECMAScript:使用 ECMAScript 語法

  • std::regex_constants::basic:使用基本的 POSIX 語法

  • std::regex_constants::extended:使用擴展的 POSIX 語法

注意:可以使用|來組合多個選項

示例

/// 只禁止輸入_,其他的可以輸入
std::regex no_underscore(R"(^[^_]*$)");/// 忽略大小寫
std::regex pattern("hello", std::regex_constants::icase);  /// 使用基本的 POSIX 語法
std::regex pattern("hello\\s\\(world\\)", std::regex_constants::basic);/// 忽略大小寫并且支持多行匹配
std::regex pattern("hello", std::regex_constants::icase | std::regex_constants::multiline);

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85693.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

OpenCV CUDA模塊設備層-----在 GPU上計算反雙曲正切函數atanh()

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 對輸入的 uchar1 像素值&#xff08;范圍 [0, 255]&#xff09;&#xff0c;先歸一化到 [0.0, 1.0] 浮點區間&#xff0c;然后計算其 反雙曲正切…

搶占西南產業高地:入駐成都芯谷金融中心文化科技產業園的價值

入駐成都芯谷金融中心文化科技產業園&#xff0c;對企業而言具有顯著的戰略價值&#xff0c;主要體現在以下幾個方面&#xff1a; 產業聚集效應與協同發展 產業鏈完善&#xff1a;成都芯谷聚焦集成電路、新型顯示、人工智能等核心產業&#xff0c;入駐企業可享受完善的產業鏈…

領域驅動設計(DDD)【2】之項目啟動與DDD基本開發流程

文章目錄 一 項目背景與目標二 核心需求分析初步需求詳細分析需求總結表 三 DDD核心概念與開發流程領域和領域專家領域驅動設計開發流程 四 潛在擴展需求 一 項目背景與目標 項目定位 開發基于SaaS的企業管理系統&#xff0c;聚焦軟件服務企業的細分市場&#xff0c;功能需求包…

深度融合數智化,百勝軟件聯合華為云加速零售行業轉型升級

當前&#xff0c;企業數字化轉型縱深推進&#xff0c;滿足企業數智化全階段、全場景的需求變得尤為關鍵。為此&#xff0c;華為云攜手上萬家伙伴共同發起第三屆828 B2B企業節&#xff0c;依托云底座為企業數智化供需“架橋”“鋪路”&#xff0c;加速企業智改數轉&#xff0c;助…

《HTTP權威指南》 第4章 連接管理

帶著問題學習&#xff08;通常是面試考點&#xff09; HTTP是如何使用TCP連接的TCP連接的時延、瓶頸及存在的障礙HTTP的優化&#xff0c;包括并行連接、keep-alive&#xff08;持久連接&#xff09;和管道化連接管理連接時應該和不應該做的事 TCP連接 TCP的數據通過IP分組&am…

StartUML入門級使用教程——畫Class類圖

一、破解安裝StartUML StarUML建模工具最新版破解安裝詳細教程https://blog.csdn.net/m0_74146638/article/details/148709643?spm1001.2014.3001.5502 二、類圖實戰 1.主界面 ? 默認打開starUML后&#xff0c;會默認進入類圖模式&#xff0c;各模塊區域功能如下&#x…

中科億海微SoM模組——FPGA+DSP核心板

FPGADSP核心板是基于中科億海微EQ6HL130型FPGA芯片搭配國產DSP開發的高性能核心板卡。對外接口采取郵票孔連接方式&#xff0c;可以極大提高信號傳輸質量和焊接后的機械強度。核心板卡的系統框圖如下圖所示。 圖 FPGADSP核心板系統框圖 FPGA采用中科億海微136K LUT資源EQ6HL130…

CentOS 7 虛擬機網絡配置異常 典型問題:啟動了NetworkManager但是network無法啟動

問題背景 在 VMware 虛擬機中使用 CentOS 7 時&#xff0c;出現以下網絡問題&#xff1a; 命令行重啟網絡服務失敗&#xff0c;提示 RTNETLINK answers: File exists 等沖突錯誤圖形界面網絡設置無法打開&#xff0c;提示需要啟動 NetworkManager網卡 ens33 無法獲取 IPv4 地…

細節/數學/滑動窗口

題目意思&#xff1a; 判斷字符串是否可以按照題目條件縮短。 思路&#xff1a; 用棧的思想寫&#xff0c;對每一次的大小寫都進行滾動判斷。 tips&#xff1a; 這里面要注意的東西就有一點多了&#xff0c;首先是字符串的遍歷問題auto更方便&#xff0c;其次是對小寫和大…

WebeServer實現:學到了哪些東西

前言 這里話就是總結一下之前沒講過的一些東西 系統調用 accept與accept4 ??當我們調用accept接收一個新的fd的時候&#xff0c;往往需要在調用fcntl將這個fd變成非阻塞IO,那么有沒有一個系統調用可以一次性做完這兩件事呢&#xff0c;有的有的就是accept4. // accept 函數…

React 虛擬dom

JSX創建出ReactElement對象 最終形成一個JS樹 將React.createElement對象轉為真實DOM的方法使用render函數 為什么要虛擬 dom 狀態難以跟蹤 ## 操作真實dom開銷大 &#xff0c;并且操作會引起頻繁的回流和重繪&#xff0c;并且不涉及批處理 聲明式編程 從虛擬dom向真實dom去…

Spring MVC異常處理機制

Spring MVC提供了多種異常處理機制,以下是核心處理方式及實現方法: 一、局部異常處理(Controller級別) @ExceptionHandler注解 在Controller內部定義異常處理方法,捕獲當前控制器拋出的指定異常。@Controller public class UserController {@GetMapping("/test"…

MySQL 8.x配置MGR高可用+ProxySQL讀寫分離(一):MGR構建MySQL高可用

#作者&#xff1a;stackofumbrella 文章目錄 簡介MGR優點MGR缺點MGR適用場景單主模式和多主模式組復制介紹組復制插件架構圖單主模式多主模式配置主機名解析安裝MGR插件 MGR故障轉移恢復MGR集群 簡介 MGR&#xff08;MySQL Group Replication&#xff09;是MySQL 5.7.17版本誕…

保安員證考試的理論知識部分,重點考查的法律法規具體有哪些?

保安員證考試理論知識部分&#xff0c;重點考查的法律法規主要有以下幾種&#xff1a; 《保安服務管理條例》&#xff1a;作為保安行業的專門法規&#xff0c;是考試核心。重點考查保安服務活動規范&#xff0c;如保安服務的范圍、資質要求等&#xff1b;保安員的權利與義務&am…

【好用但慎用】Windows 系統中將所有 WSL 發行版從 C 盤遷移到 非系統 盤的完整筆記(附 異常處理)

&#x1f680; 將所有 WSL 發行版從 C 盤遷移到 I 盤的完整教程&#xff08;含 Podman / NVIDIA Workbench / Ubuntu 等&#xff09; 【無標題】使用 Chocolatey 安裝 WSL 管理工具 LxRunOffline-CSDN博客 免責聲明 重要提示 在執行 WSL 遷移操作前&#xff0c;請務必仔細閱讀…

Oracle APEX 通過rtf模板下載PDF文件(BIP)

1. 上傳模板文件 共享組件 > 報表布局 2. 編寫SQL文 共享組件 > 報表查詢 報表布局中選擇1中設置完的報表布局&#xff0c;然后編寫SQL文提供數據 3. 添加下載按鈕 在頁中添加一個下載按鈕&#xff0c;添加動態操作&#xff0c;選擇打印報告 4. 下載PDF文件 點擊Pri…

Web Seach 搜索 MCP 啟動!

&#x1f680; 開啟你的 AI 助手搜索能力&#xff01;開源 Web 搜索 MCP 服務器上線&#xff01; 在 ChatGPT、Claude 等 AI 工具成為生產力新核心的今天&#xff0c;我們往往面臨一個尷尬的問題&#xff1a;模型不知道最新的網絡信息。雖然 GPT-4o 和 Claude 支持聯網功能&am…

005微信小程序npm包_全局數據共享和分包

npm包_全局數據共享和分包 1. 使用npm包1.1 Vant Weapp1.2 API Promise化 2. 全局數據共享3. 分包3.1 分包的加載規則3.2 分包的體積限制3.3 使用分包3.3 獨立分包3.4 分包預下載 1. 使用npm包 小程序對npm進行了支持與限制&#xff0c;限制如下&#xff1a; 不支持依賴于 No…

DPO直接偏好函數的學習解讀

DPO, Direct Preference Optimization&#xff0c;采用直接優化策略滿足人類偏好&#xff0c;使得LLM對于給定輸入&#xff0c;生成能用輸出的概率高于生成不能用輸出的概率。 1&#xff09;DPO優化目標 在DPO訓練過程中&#xff0c;模型通過最大化可用回答相對于不可用回答的…

【開源初探】基于 Qwen2.5VL的文檔解析工具:docext

源碼地址&#xff1a; https://github.com/NanoNets/docext 概述 docext 是一個由視覺語言模型&#xff08;vlm&#xff09;提供支持的全面的本地文檔智能工具包。vlm 使用的是基于 Qwen2.5VL-3B 的模型&#xff0c;應該是在此模型基礎上進行的微調。 它提供了三個核心功能&…