正則表達式(轉)

  • 正則表達式的用途

  https://msdn.microsoft.com/zh-cn/library/101eysae(v=vs.90).aspxhtml

  經過使用正則表達式,能夠:node

  一、測試字符串內的模式linux

    例如,能夠測試輸入字符串,以查看字符串內是否出現電話號碼模式或信用卡號碼模式。這稱爲數據驗證。正則表達式

  二、替換文本shell

    可使用正則表達式來識別文檔中的特定文本,徹底刪除該文本或者用其餘文本替換它。express

  三、基於模式匹配從字符串中提取子字符串ubuntu

    能夠查找文檔內或輸入域內特定的文本。數組

  • 正則表達式語法

  https://msdn.microsoft.com/zh-cn/library/ae5bf541(v=vs.90).aspxapp

  正則表達式是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱爲「元字符」)。模式描述在搜索文本時要匹配的一個或多個字符串。工具

  下表包含了元字符的完整列表以及它們在正則表達式上下文中的行爲:

字符

說明

\

將下一字符標記爲特殊字符、文本、反向引用或八進制轉義符。例如,「n」匹配字符「n」。「\n」匹配換行符。序列「\\」匹配「\」,「\(」匹配「(」。

^

匹配輸入字符串開始的位置。若是設置了 RegExp對象的 Multiline 屬性,^ 還會與「\n」或「\r」以後的位置匹配。

$

匹配輸入字符串結尾的位置。若是設置了 RegExp對象的 Multiline 屬性,$ 還會與「\n」或「\r」以前的位置匹配。

*

零次或屢次匹配前面的字符或子表達式。例如,zo* 匹配「z」和「zoo」。* 等效於 {0,}。

+

一次或屢次匹配前面的字符或子表達式。例如,「zo+」與「zo」和「zoo」匹配,但與「z」不匹配。+ 等效於 {1,}。

?

零次或一次匹配前面的字符或子表達式。例如,「do(es)?」匹配「do」或「does」中的「do」。? 等效於 {0,1}。

{n}

是非負整數。正好匹配 n 次。例如,「o{2}」與「Bob」中的「o」不匹配,但與「food」中的兩個「o」匹配。

{n,}

是非負整數。至少匹配 次。例如,「o{2,}」不匹配「Bob」中的「o」,而匹配「foooood」中的全部 o。「o{1,}」等效於「o+」。「o{0,}」等效於「o*」。

{n,m}

M 和 n 是非負整數,其中 n <= m。匹配至少 n次,至多 m 次。例如,「o{1,3}」匹配「fooooood」中的頭三個 o。'o{0,1}' 等效於 'o?'。注意:您不能將空格插入逗號和數字之間。

?

當此字符緊隨任何其餘限定符(*、+、?、{n}、{n,}、{n,m})以後時,匹配模式是「非貪心的」。「非貪心的」模式匹配搜索到的、儘量短的字符串,而默認的「貪心的」模式匹配搜索到的、儘量長的字符串。例如,在字符串「oooo」中,「o+?」只匹配單個「o」,而「o+」匹配全部「o」。

.

匹配除「\n」以外的任何單個字符。若要匹配包括「\n」在內的任意字符,請使用諸如「[\s\S]」之類的模式。

(pattern)

匹配 pattern 並捕獲該匹配的子表達式。可使用$0…$9 屬性從結果「匹配」集合中檢索捕獲的匹配。若要匹配括號字符 ( ),請使用「\(」或者「\)」。

(?:pattern)

匹配 pattern 但不捕獲該匹配的子表達式,即它是一個非捕獲匹配,不存儲供之後使用的匹配。這對於用「or」字符 (|) 組合模式部件的狀況頗有用。例如,'industr(?:y|ies) 是比 'industry|industries' 更經濟的表達式。

(?=pattern)

執行正向預測先行搜索的子表達式,該表達式匹配處於匹配 pattern 的字符串的起始點的字符串。它是一個非捕獲匹配,即不能捕獲供之後使用的匹配。例如,'Windows (?=95|98|NT|2000)' 匹配「Windows 2000」中的「Windows」,但不匹配「Windows 3.1」中的「Windows」。預測先行不佔用字符,即發生匹配後,下一匹配的搜索緊隨上一匹配以後,而不是在組成預測先行的字符後。

(?!pattern)

執行反向預測先行搜索的子表達式,該表達式匹配不處於匹配 pattern 的字符串的起始點的搜索字符串。它是一個非捕獲匹配,即不能捕獲供之後使用的匹配。例如,'Windows (?!95|98|NT|2000)' 匹配「Windows 3.1」中的 「Windows」,但不匹配「Windows 2000」中的「Windows」。預測先行不佔用字符,即發生匹配後,下一匹配的搜索緊隨上一匹配以後,而不是在組成預測先行的字符後。

x|y

匹配 x 或 y。例如,'z|food' 匹配「z」或「food」。'(z|f)ood' 匹配「zood」或「food」。

[xyz]

字符集。匹配包含的任一字符。例如,「[abc]」匹配「plain」中的「a」。

[^xyz]

反向字符集。匹配未包含的任何字符。例如,「[^abc]」匹配「plain」中的「p」。

[a-z]

字符範圍。匹配指定範圍內的任何字符。例如,「[a-z]」匹配「a」到「z」範圍內的任何小寫字母。

[^a-z]

反向範圍字符。匹配不在指定的範圍內的任何字符。例如,「[^a-z]」匹配任何不在「a」到「z」範圍內的任何字符。

\b

匹配一個字邊界,即字與空格間的位置。例如,「er\b」匹配「never」中的「er」,但不匹配「verb」中的「er」。

\B

非字邊界匹配。「er\B」匹配「verb」中的「er」,但不匹配「never」中的「er」。

\cx

匹配 x 指示的控制字符。例如,\cM 匹配 Control-M 或回車符。x 的值必須在 A-Z 或 a-z 之間。若是不是這樣,則假定 c 就是「c」字符自己。

\d

數字字符匹配。等效於 [0-9]。

\D

非數字字符匹配。等效於 [^0-9]。

\f

換頁符匹配。等效於 \x0c 和 \cL。

\n

換行符匹配。等效於 \x0a 和 \cJ。

\r

匹配一個回車符。等效於 \x0d 和 \cM。

\s

匹配任何空白字符,包括空格、製表符、換頁符等。與 [ \f\n\r\t\v] 等效。

\S

匹配任何非空白字符。與 [^ \f\n\r\t\v] 等效。

\t

製表符匹配。與 \x09 和 \cI 等效。

\v

垂直製表符匹配。與 \x0b 和 \cK 等效。

\w

匹配任何字類字符,包括下劃線。與「[A-Za-z0-9_]」等效。

\W

與任何非單詞字符匹配。與「[^A-Za-z0-9_]」等效。

\xn

匹配 n,此處的 n 是一個十六進制轉義碼。十六進制轉義碼必須正好是兩位數長。例如,「\x41」匹配「A」。「\x041」與「\x04」&「1」等效。容許在正則表達式中使用 ASCII 代碼。

\num

匹配 num,此處的 num 是一個正整數。到捕獲匹配的反向引用。例如,「(.)\1」匹配兩個連續的相同字符。

\n

標識一個八進制轉義碼或反向引用。若是 \n 前面至少有 n 個捕獲子表達式,那麼 n 是反向引用。不然,若是 n 是八進制數 (0-7),那麼 n 是八進制轉義碼。

\nm

標識一個八進制轉義碼或反向引用。若是 \nm 前面至少有 nm 個捕獲子表達式,那麼 nm 是反向引用。若是 \nm 前面至少有 n 個捕獲,則 n 是反向引用,後面跟有字符 m。若是兩種前面的狀況都不存在,則 \nm 匹配八進制值 nm,其中 和 m 是八進制數字 (0-7)。

\nml

當 n 是八進制數 (0-3),m 和 l 是八進制數 (0-7) 時,匹配八進制轉義碼 nml

\un

匹配 n,其中 n 是以四位十六進制數表示的 Unicode 字符。例如,\u00A9 匹配版權符號 (©)。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 生成正則表達式

 https://msdn.microsoft.com/zh-cn/library/6h0s3kc9(v=vs.90).aspx

  正則表達式的結構與算術表達式的結構相似。即,各類元字符和運算符能夠將小的表達式組合起來,建立大的表達式。

  分隔符

  經過在一對分隔符之間放置表達式模式的各類組件,就能夠構建正則表達式。對於 JScript,分隔符是正斜槓 (/) 字符。例如:

 

   /expression/

 

  在上面的示例中,正則表達式模式 (expression) 存儲在 RegExp 對象的 Pattern 屬性中。

 

  正則表達式的組件能夠是單個字符、字符集、字符的範圍、在幾個字符之間選擇或者全部這些組件的任何組合。

  • 優先級順序

  下表從最高到最低說明了各類正則表達式運算符的優先級順序:

運算符

說明

\

轉義符

(), (?:), (?=), []

括號和中括號

*, +, ?, {n}, {n,}, {n,m}

限定符

^, $, \任何元字符、任何字符

定位點和序列

|

替換

 

  

 

 

 

 

 

 

 

 

 

字符具備高於替換運算符的優先級,使得「m|food」匹配「m」或「food」。若要匹配「mood」或「food」,請使用括號建立子表達式,從而產生「(m|f)ood」。

  

  • 字符匹配

  https://msdn.microsoft.com/zh-cn/library/901zys3s(v=vs.90).aspx

  句點 (.) 匹配字符串中的各類打印或非打印字符,只有一個字符例外。這個例外就是換行符 (\n)。下面的正則表達式匹配 aac、abc、acc、adc 等等,以及 a1c、a2c、a-c 和 a#c:

 
  /a.c/

  若要匹配包含文件名的字符串,而句點 (.) 是輸入字符串的組成部分,請在正則表達式中的句點前面加反斜扛 (\) 字符。舉例來講明,下面的正則表達式匹配 filename.ext:

/filename\.ext/

這些表達式只讓您匹配「任何」單個字符。可能須要匹配列表中的特定字符組。例如,可能須要查找用數字表示的章節標題(Chapter 一、Chapter 2 等等)。

  中括號表達式
   要建立匹配字符組的一個列表,請在方括號([ 和 ])內放置一個或更多單個字符。當字符括在中括號內時,該列表稱爲「中括號表達式」。與在任何別的位置同樣,普通字符在中括號內表示其自己,即,它在輸入文本中匹配一次其自己。大多數特殊字符在中括號表達式內出現時失去它們的意義。不過也有一些例外,如:
  一、若是 ] 字符不是第一項,它結束一個列表。若要匹配列表中的 ] 字符,請將它放在第一位,緊跟在開始 [ 後面。
  二、\ 字符繼續做爲轉義符。若要匹配 \ 字符,請使用 \\。

  括在中括號表達式中的字符只匹配處於正則表達式中該位置的單個字符。如下正則表達式匹配 Chapter 一、Chapter 二、Chapter 三、Chapter 4 和 Chapter 5:

  /Chapter [12345]/

  請注意,單詞 Chapter 和後面的空格的位置相對於中括號內的字符是固定的。中括號表達式指定的只是匹配緊跟在單詞 Chapter 和空格後面的單個字符位置的字符集。這是第九個字符位置。

  若要使用範圍代替字符自己來表示匹配字符組,請使用連字符 (-) 將範圍中的開始字符和結束字符分開。單個字符的字符值肯定範圍內的相對順序。下面的正則表達式包含範圍表達式,該範圍表達式等效於上面顯示的中括號中的列表。

/Chapter [1-5]/

  當以這種方式指定範圍時,開始值和結束值二者都包括在範圍內。注意,還有一點很重要,按 Unicode 排序順序,開始值必須在結束值的前面。

  若要在中括號表達式中包括連字符,請採用下列方法之一:

  一、用反斜扛將它轉義:

   
  • [\-]
  二、將連字符放在中括號列表的開始或結尾。下面的表達式匹配全部小寫字母和連字符:
  
  • [-a-z]
 
    
  • [a-z-]
  • 三、建立一個範圍,在該範圍中,開始字符值小於連字符,而結束字符值等於或大於連字符。下面的兩個正則表達式都知足這一要求:

   [!-~]

  若要查找不在列表或範圍內的全部字符,請將插入符號 (^) 放在列表的開頭。若是插入字符出如今列表中的其餘任何位置,則它匹配其自己。下面的正則表達式匹配編號大於 5 的章節標題:

  /Chapter [^12345]/

  在上面的示例中,表達式在第九個位置匹配 一、二、三、4 或 5 以外的任何數字字符。這樣,例如,Chapter 7 就是一個匹配項,Chapter 9 也是一個匹配項。

  上面的表達式可使用連字符 (-) 來表示:

  /Chapter [^1-5]/

  中括號表達式的典型用途是指定任何大寫或小寫字母或任何數字的匹配。下面的表達式指定這樣的匹配:

  /[A-Za-z0-9]/


深刻淺出C/C++中的正則表達式庫(一)——GNU Regex Library

原文:http://www.wuzesheng.com/?p=929

寫在前面: 本文是面向有正則表達式基礎的讀者朋友的,若是你還不知道正則表達式是什麼,請先到這裏學習一下

正則表達式(Regular Expressions),又被稱爲regex或regexp,是一種十分簡便、靈活的文本處理工具。它能夠用來精確地找出某文本中匹配某種指定規則的內容。在linux下,grep, sed, awk等工具都支持正則表達式,這些工具的存在,爲咱們平常的文本處理帶來了極大的便利。可是,有時候,咱們本身寫的程序中也須要用到正則表達式來處理一些文本,這時候就須要一些正則表達式庫的支持了。因爲我本人是用C/C++作爲主要開發語言的,因此,在本文以及接下來的幾篇文章中,我將介紹幾個經常使用的C/C++的正則表達式的庫,經過個人介紹,以及對具體的使用進行舉例,但願可以給讀者朋友在C/C++程序中使用正則表達式時有點幫助,這將是我莫大的榮幸。

當前,據我所知,在C/C++中經常使用的正則表達式庫有GNU Regex Library, Boost.Regex, PCRE, PCRE++。這四個庫中,後面兩個是有關係,其它都是各本身獨立的,是不一樣的實現。所以我會分三次,來一一對這四個庫進行介紹。今天首先介紹一下GNU Regex Library。

1. 什麼是GNU正則表達式庫(GNU Regex Library) ?
GNU正則表達式庫是glibc(GNU C Library)的一部分,它提供與POSIX標準兼容的正則表達式匹配的接口。
這裏是其主頁:http://www.gnu.org/s/libc/manual/html_node/Regular-Expressions.html
下載該庫點這裏:gnuregex0_13 

2. GNU Regex Library所提供的接口
(1)regcomp:

1
2
3
4
5
6
int regcomp(regex_t *preg, const char *pattern, int cflags)
功能:將要進行匹配的正則表達式pattern進行編譯,作匹配前的準備工做
參數: preg, 輸出參數,用來保存編譯後的正則表達式結果
      pattern, 輸入參數,傳入要進行編譯的正則表達式的字符串
      cflags, 輸入參數,用來指定正則表達式匹配過程當中的一些選項
返回值:編譯成功返回0,失敗返回非0的錯誤碼

 

 

 

 

(2)regexec:

1
2
3
4
5
6
7
8
9
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], 
            int eflags)
功能:用來檢測字符串string是否匹配正則表達式preg
參數: preg, 輸入參數,在(1)regcomp中編譯好的正則表達式規則
      string, 輸入參數,用來被匹配的字符串
      nmatch, 輸入參數,用來指定pmatch參數所對應的數組的長度
      pmatch, 輸出參數,用來輸出在string中匹配preg的具體位置
      eflag, 輸入參數,用來指定正則表達式匹配過程當中的一些選項
返回值: 若是string匹配preg所指定的規則,則返回0, 不然返回非0

 

 

 

 

 

 

(3)regerror:

1
2
3
4
5
6
7
size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size)
功能:用來把在regcompt和regexec中產生的錯誤碼轉化成字符串形式的錯誤信息
參數: errcode, 輸入參數,在regcomp或regexec調用中返回的錯誤碼
      preg, 輸入參數,與錯誤碼所對應的編譯過的正則表達式結構
      errbuf, 輸出參數,用來返回錯誤信息的buffer,若是buffer不夠所需大小,錯誤信息將被截斷
      errbuf_size, 輸入參數,返回錯誤信息的buffer的大小 
返回值: 若是errbuf_size爲0,那麼regerror返回錯誤信息所須要的buffer的大小

 

 

 

 

 

(4)regfree:

1
2
3
4
void regfree (regex_t *preg)
功能: 用來釋放由regcomp編譯時生成的preg結構所佔用的內存
參數: preg, 輸入參數,由regcomp編譯時生成的正則表達的結構指針
返回值: 無

 

 

 

3. 使用GNU Regex Library的一些注意事項
(1)regcomp與regfree必須配對使用,要否則會形成內存泄漏(類比malloc/free, new/delete)
(2)regex_t結構:把字符串形式的正則表達式編譯成regex_t這樣的一個結構,方便後續的匹配工做
(3)regmatch_t結構:用來表示正則表達式中字符串中匹配的位置的結構,用起始位置的偏移量來表示的
(4)flags:用來配置匹配過程當中的一些選項, 指定如何匹配,具體參見:http://www.opengroup.org/onlinepubs/007908799/xsh/regcomp.html
(5)使用該庫須要包含的頭文件:sys/types.h和regex .h

4. GNU Regex Library使用舉例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <sys /types.h>
#include <regex .h>
#include <stdio .h>
 
int main(int argc, char ** argv)
{
    if (argc != 3)
    {
        printf("Usage: %s RegexString Text\n", argv[0]);
        return 1;
    }
 
    const char * pRegexStr = argv[1];
    const char * pText = argv[2];
 
    regex_t oRegex;
    int nErrCode = 0;
    char szErrMsg[1024] = {0};
    size_t unErrMsgLen = 0;
 
    if ((nErrCode = regcomp(&oRegex, pRegexStr, 0)) == 0)
    {
        if ((nErrCode = regexec(&oRegex, pText, 0, NULL, 0)) == 0)
        {
            printf("%s matches %s\n", pText, pRegexStr);
            regfree(&oRegex);
            return 0;
        }
    }
 
    unErrMsgLen = regerror(nErrCode, &oRegex, szErrMsg, sizeof(szErrMsg));
    unErrMsgLen = unErrMsgLen < sizeof(szErrMsg) ? unErrMsgLen : sizeof(szErrMsg) - 1;
    szErrMsg[unErrMsgLen] = '\0';
    printf("ErrMsg: %s\n", szErrMsg);
 
    regfree(&oRegex);
    return 1;
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

程序測試:

1
2
3
4
5
wuzesheng@wuzesheng-ubuntu:~/Program$ gcc TestRegex.c -o Regex
wuzesheng@wuzesheng-ubuntu:~/Program$ ./Regex "http:\/\/www\..*\.com" "https://www.taobao.com"
ErrMsg: No match
wuzesheng@wuzesheng-ubuntu:~/Program$ ./Regex "http:\/\/www\..*\.com" "http://www.taobao.com"
http://www.taobao.com matches http:\/\/www\..*\.com

 

 

 

 

以上便是關於GNU Regex Library的所有內容。若是讀書者朋友有什麼見解能夠在下面給我留言。接下來幾天,我會陸續介紹前面提到的其它幾個庫,今天先到這裏。

 

做者關於另兩種庫進行正則表達式匹配文章:

深刻淺出C/C++中的正則表達式庫(二)——Boost.Regex      http://www.wuzesheng.com/?p=965

 深刻淺出C/C++中的正則表達式庫(三)——PCRE, PCRE++ http://www.wuzesheng.com/?p=994

相關文章
相關標籤/搜索