亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C > 正文

C語言中的正則表達式使用示例詳解

2020-01-26 13:25:59
字體:
來源:轉載
供稿:網友

正則表達式,又稱正規表示法、常規表示法(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE)。正則表達式是使用單個字符串來描述、匹配一系列符合某個句法規則的字符串。

在c語言中,用regcomp、regexec、regfree 和regerror處理正則表達式。處理正則表達式分三步:

  1. 編譯正則表達式,regcomp;
  2. 匹配正則表達式,regexec;
  3. 釋放正則表達式,regfree。

函數原型

/*函數說明:Regcomp將正則表達式字符串regex編譯成regex_t的形式,后續regexec以此進行搜索。參數說明:  Preg:一個regex_t結構體指針。  Regex:正則表達式字符串。  Cflags:是下邊四個值或者是他們的或(|)運算。    REG_EXTENDED:使用POSIX擴展正則表達式語法解釋的正則表達式。如果沒有設置,基本POSIX正則表達式語法。    REG_ICASE:忽略字母的大小寫。    REG_NOSUB:不存儲匹配的結果。    REG_NEWLINE:對換行符進行“特殊照顧”,后邊詳細說明。返回值:  0:表示成功編譯;  非0:表示編譯失敗,用regerror查看失敗信息*/int regcomp(regex_t *preg, const char *regex, int cflags);/*函數說明: Regexec用來匹配正則文本。參數說明:  Preg:由regcomp編譯好的regex_t結構體指針,  String:要進行正則匹配的字符串。  Nmatch:regmatch_t結構體數組的大小  Pmatch:regmatch_t結構體數組。用來保存匹配結果的子串位置。  regmatch_t結構體定義如下    typedef struct {      regoff_t rm_so;      regoff_t rm_eo;    } regmatch_t;    rm_so,它的值如果不為-1,表示匹配的最大子串在字符串中的起始偏移量,rm_eo,表示匹配的最大字串在字符串的結束偏移量。  Eflags: REG_NOTBOL和REG_NOTEOL為兩個值之一或二者的或(|)運算,稍后會介紹。返回值:  0:表示成功編譯;  非0:表示編譯失敗,用regerror查看失敗信息*/int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);/*函數說明:用來釋放regcomp編譯好的內置變量。參數說明:  Preg:由regcomp編譯好的regex_t結構體指針。*/void regfree(regex_t *preg);/*函數說明:Regcomp,regexec出錯時,會返回error code并且為非0,此時就可以用regerror得到錯誤信息。參數說明:  Errcode:Regcomp,regexec出錯時的返回值  Preg:經過Regcomp編譯的regex_t結構體指針。  Errbuf:錯誤信息放置的位置。  errbuf_size:錯誤信息buff的大小。*/size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);

示例一

#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "Hello World";  char *reg_str = "H.*";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "%s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 0, NULL, 0);  if (ret)  {    regerror(ret, ®, ebuff, 256);    fprintf(stderr, "%s/n", ebuff);    goto end;  }    regerror(ret, ®, ebuff, 256);  fprintf(stderr, "result is:/n%s/n", ebuff);end:  regfree(®);  return 0;}

編譯,輸出結果:

[root@zxy regex]# ./test
result is:
Success

匹配成功。

示例二

如果我想保留匹配的結果怎么操作?那就得用到 regmatch_t 結構體了。重新改寫上邊代碼,這時就不能用REG_NOSUB選項了,代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  regmatch_t rm[5];  char *part_str = NULL;  cflags = REG_EXTENDED | REG_ICASE;  char *test_str = "Hello World";  char *reg_str = "e(.*)o";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "%s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 5, rm, 0);   if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "%s/n", ebuff);    goto end;  }  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "result is:/n%s/n/n", ebuff);  for (i=0; i<5; i++)  {    if (rm[i].rm_so > -1)    {      part_str = strndup(test_str+rm[i].rm_so, rm[i].rm_eo-rm[i].rm_so);      fprintf(stderr, "%s/n", part_str);      free(part_str);      part_str = NULL;    }  }end:  regfree(®);  return 0;}

編譯,輸出結果:

[root@zxy regex]# ./test
result is:
Success
ello Wo
llo W

  咦??????我明明只要一個匹配結果,為什么會打印兩個出來呢???????
  原來regmatch_t數組的第一個元素是有特殊意義的:它是用來保存整個正則表達式能匹配的最大子串的起始和結束偏移量。所以我們在設置regmatch_t數組個數的時候一定要記住,它的個數是最大保留結果數+1。

REG_NEWLINE、REG_NOTBOL和REG_NOTEOL

好了,基本的正則運用到此為止了,現在要開始講講REG_NEWLINE、REG_NOTBOL和REG_NOTEOL。很多人對這三個參數有所迷惑。我也是,昨天有人問問題,就把自己錯誤的理解告訴了別人,然后被大神一頓鄙視。我一直認為如果想用^和$這兩個匹配模式一定要用到REG_NEWLINE這個參數,其實不然。

REG_NEWLINE

首先看下man page對REG_NEWLINE的說明:

REG_NEWLINE  Match-any-character operators don't match a newline.  A non-matching list ([^...]) not containing a newline does not match a newline.  Match-beginning-of-line operator (^) matches the empty string immediately after a newline, regardless of whether eflags, the execution flags of regexec(), contains REG_NOTBOL.  Match-end-of-line operator ($) matches the empty string immediately before a newline, regardless of whether eflags contains REG_NOTEOL.

我英文不好,google翻譯之。。

REG_NEWLINE

  1.匹配任何字符的運算符(比如.)不匹配換行('/n');
  2.非匹配列表([^...])不包含一個換行符不匹配一個換行符;
  3.匹配開始運算符(^)遇到空字符串立即換行,不論在執行regexec()時,eflags是否設置了REG_NOTBOL;
  4.匹配結束運算符($)遇到空字符串立即換行,不論在執行regexec()時,eflags是否設置了REG_NOTEOL;

不明白說的是什么,程序測之。。

第一個問題

代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "Hello World/n";  char *reg_str = "Hello World.";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "1. %s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 0, NULL, 0);   regerror(ret, ®, ebuff, 256);  fprintf(stderr, "2. %s/n", ebuff);  cflags |= REG_NEWLINE;  ret = regcomp(®, reg_str, cflags);  if (ret)  {    regerror(ret, ®, ebuff, 256);    fprintf(stderr, "3. %s/n", ebuff);    goto end;  }  ret = regexec(®, test_str, 0, NULL, 0);  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "4. %s/n", ebuff);end:  regfree(®);  return 0;}

  編譯,運行結果如下:

[root@zxy regex]# ./test
2. Success
4. No match

  結果很明顯:沒有加入REG_NEWLINE的匹配成功,加入的匹配不成功。就是說不加入REG_NEWLINE,任意匹配字符(.)包含'n',加入則不包含'n'。

第二個問題

代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "Hello/nWorld";  char *reg_str = "Hello[^ ]";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "1. %s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 0, NULL, 0);   regerror(ret, ®, ebuff, 256);  fprintf(stderr, "2. %s/n", ebuff);  cflags |= REG_NEWLINE;  ret = regcomp(®, reg_str, cflags);  if (ret)  {    regerror(ret, ®, ebuff, 256);    fprintf(stderr, "3. %s/n", ebuff);    goto end;  }  ret = regexec(®, test_str, 0, NULL, 0);  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "4. %s/n", ebuff);end:  regfree(®);  return 0;}

編譯,運行結果如下:

[root@zxy regex]# ./test
2. Success
4. No match

  結果說明:不加入REG_NEWLINE,在一個不包含'n'的非列表中,'n'是不被認作空白符,加入則'n'是被認作空白符。

第三個問題

代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "/nHello World";  char *reg_str = "^Hello";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "1. %s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 0, NULL, 0);   regerror(ret, ®, ebuff, 256);  fprintf(stderr, "2. %s/n", ebuff);  cflags |= REG_NEWLINE;  ret = regcomp(®, reg_str, cflags);  if (ret)  {    regerror(ret, ®, ebuff, 256);    fprintf(stderr, "3. %s/n", ebuff);    goto end;  }  ret = regexec(®, test_str, 0, NULL, 0);  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "4. %s/n", ebuff);end:  regfree(®);  return 0;}

編譯,運行結果如下:

[root@zxy regex]# ./test
2. No match
4. Success

  結果說明:不加入REG_NEWLINE,'^'是不忽略'n'的,加入REG_NEWLINE,'^'是忽略'n'的。也就是說:不加入REG_NEWLINE,以'n'開頭的字符串是不能用'^'匹配,加入REG_NEWLINE,以'n'開頭的字符串是可以用'^'匹配。

第四個問題

代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "Hello World/n";  char *reg_str = "d$";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "1. %s/n", ebuff);    goto end;  }    ret = regexec(®, test_str, 0, NULL, 0);   regerror(ret, ®, ebuff, 256);  fprintf(stderr, "2. %s/n", ebuff);  cflags |= REG_NEWLINE;  ret = regcomp(®, reg_str, cflags);  if (ret)  {    regerror(ret, ®, ebuff, 256);    fprintf(stderr, "3. %s/n", ebuff);    goto end;  }  ret = regexec(®, test_str, 0, NULL, 0);  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "4. %s/n", ebuff);end:  regfree(®);  return 0;}

編譯,運行結果如下:

[root@zxy regex]# ./test
2. No match
4. Success

  結果說明:不加入REG_NEWLINE,'$'是不忽略'n'的,加入REG_NEWLINE,'$'是忽略'n'的。也就是說:不加入REG_NEWLINE,以'n'結尾的字符串是不能用'​$'匹配,加入REG_NEWLINE,以'n'開頭的字符串是可以用'​$'匹配。

REG_NEWLINE總結

好,REG_NEWLINE選項測試到此結束??偨Y下:

  對于REG_NEWLINE選項,1.使用任意匹配符(.)時,任意匹配符不會包含'n';2.對于一個不含有'n'的非列表,會把'n'認作空白符。3.對于以'n'開頭或結尾的字符串,會忽略'n'。使'^'和'$'可以使用。

REG_NOTBOL和REG_NOTEOL

現在開始說下REG_NOTBOL和REG_NOTEOL,首先看下man page對這兩選項的說明:

REG_NOTBOL  The match-beginning-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above) This flag may be used when different portions of a string are passed to regexec() and the beginning of the string should not be interpreted as the beginning of the line.REG_NOTEOL  The match-end-of-line operator always fails to match (but see the compilation flag REG_NEWLINE above)繼續googling。

REG_NOTBOL
  匹配開始操作符(^)會經常匹配失敗(但是要考慮REG_NEWLINE),這個標志被用在當一個字符串的不同位置被傳入到regexec()時,這個位置不應該被解釋為該整個字符串的開始位置。
REG_NOTEOL
  匹配結束操作符($)會經常失敗(但是要考慮REG_NEWLINE)。(這個標志被用在當一個字符串的不同位置被傳入到regexec()時,即使滿足匹配結束作符,也不應該被解釋為以某字符(串)為結束的)。

  好吧,繼續測試,第一個問題代碼如下:

#define _GNU_SOURCE#include <string.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <regex.h>int main (void){  int i;  char ebuff[256];  int ret;  int cflags;  regex_t reg;  cflags = REG_EXTENDED | REG_ICASE | REG_NOSUB;  char *test_str = "Hello World/n";  char *reg_str = "^e";  ret = regcomp(®, reg_str, cflags);  if (ret)  {      regerror(ret, ®, ebuff, 256);    fprintf(stderr, "1. %s/n", ebuff);    goto end;  }    ret = regexec(®, test_str+1, 0, NULL, 0);   regerror(ret, ®, ebuff, 256);  fprintf(stderr, "2. %s/n", ebuff);  ret = regexec(®, test_str+1, 0, NULL, REG_NOTBOL);  regerror(ret, ®, ebuff, 256);  fprintf(stderr, "4. %s/n", ebuff);end:  regfree(®);  return 0;}

編譯,運行結果如下:

[root@zxy regex]# ./test
2. Success
4. No match

結果說明:不加入REG_NOTBOL,一個字符串的不同位置是可以用'^'進行匹配,加入REG_NOTBOL,則不能進行匹配。

第二個問題,我實在理解不了了,網上介紹的全是沒有經過驗證的。。。。。。

總結

以上所述是小編給大家介紹的C語言中的正則表達式使用示例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對武林網網站的支持!
如果你覺得本文對你有幫助,歡迎轉載,煩請注明出處,謝謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
精品日本高清在线播放| 最近2019免费中文字幕视频三| 69影院欧美专区视频| 久久久精品久久久| 日韩成人网免费视频| 一本色道久久综合狠狠躁篇的优点| 中文字幕自拍vr一区二区三区| 理论片在线不卡免费观看| 欧美日韩亚洲网| 亚洲精品在线看| 亚洲综合日韩中文字幕v在线| 国产精品自产拍在线观看| 欧美激情女人20p| 2019最新中文字幕| 97视频在线播放| 在线电影欧美日韩一区二区私密| 91深夜福利视频| 欧洲美女免费图片一区| 91久久精品在线| 黄色一区二区三区| 精品国产精品三级精品av网址| 亚洲精美色品网站| 日韩av在线一区二区| 国产精品啪视频| 亚洲激情自拍图| 自拍偷拍亚洲欧美| 热re99久久精品国产66热| 国产91色在线免费| 高清欧美性猛交| 性欧美xxxx视频在线观看| 久久精品青青大伊人av| 国产精品美女主播在线观看纯欲| 国产欧美精品日韩| 欧美成人黄色小视频| 色阁综合伊人av| 欧美乱大交做爰xxxⅹ性3| 亚洲色图五月天| 久久久久女教师免费一区| 欧美肥臀大乳一区二区免费视频| 国产亚洲福利一区| 国产91成人在在线播放| 国模精品视频一区二区| 欧美性猛交xxxx免费看久久久| 在线观看亚洲区| 久久精品青青大伊人av| 国产女同一区二区| 久久99精品视频一区97| 亚洲欧美成人一区二区在线电影| 国产亚洲精品久久久| 欧美性高跟鞋xxxxhd| 国产欧美va欧美va香蕉在| 国产精品嫩草影院一区二区| 亚洲a中文字幕| 国产欧美日韩视频| 亚洲精品动漫久久久久| 久久久久久久国产精品| 另类少妇人与禽zozz0性伦| 亚洲va久久久噜噜噜久久天堂| 欧美精品在线视频观看| 97视频免费观看| 中文字幕国产亚洲2019| 日韩一区二区三区在线播放| 国产欧美一区二区三区四区| 91超碰中文字幕久久精品| 日韩欧美在线第一页| 国产精品美乳一区二区免费| 欧美精品制服第一页| 91免费精品国偷自产在线| 亚洲大胆美女视频| 国产亚洲激情视频在线| 亚洲直播在线一区| 久久精品国产69国产精品亚洲| 欧美日韩午夜激情| 久久精品国产99国产精品澳门| 中文字幕欧美日韩| 97视频色精品| 亚洲一区二区免费在线| 亚洲欧美日韩另类| 亚洲精品美女久久久久| 亚洲精品久久久久久久久| 欧美激情亚洲自拍| 日韩久久午夜影院| 亚洲一区二区三区777| 久久99久久久久久久噜噜| 欧美超级免费视 在线| 亚洲国产精品大全| 在线观看精品国产视频| 国内精品小视频在线观看| 亚洲国产精品va在线观看黑人| 国产精品夫妻激情| 国产精品激情av电影在线观看| 欧美日韩高清在线观看| 国产精品亚洲综合天堂夜夜| 亚洲免费电影在线观看| 日韩在线观看av| 精品国产福利在线| 色综久久综合桃花网| 91精品国产自产在线| 欧美性猛交xxxx免费看久久久| 91九色国产视频| 最新69国产成人精品视频免费| 91亚洲精品一区二区| 亚洲天堂成人在线| 亚洲国产精品字幕| 久久久视频在线| 亚洲精品白浆高清久久久久久| 91丨九色丨国产在线| 播播国产欧美激情| 日韩中文字幕在线视频| 大胆欧美人体视频| 久久久久久久av| 激情懂色av一区av二区av| 91精品久久久久久久久久| 欧美国产日韩一区二区在线观看| 按摩亚洲人久久| 成人网在线免费看| 国产日产欧美精品| 久久久久久久一区二区| 日韩美女视频中文字幕| 日韩欧美a级成人黄色| 日本一区二区三区四区视频| 国产欧美日韩免费| 午夜精品视频在线| 亚洲欧美国产一本综合首页| 91地址最新发布| 国产亚洲精品日韩| 欧美中文在线观看国产| 欧美日产国产成人免费图片| 国产成人在线亚洲欧美| 国产成人在线一区| 亚洲人成亚洲人成在线观看| 亚洲精品免费网站| 欧美精品电影免费在线观看| 精品一区二区三区四区在线| 久操成人在线视频| 欧美专区第一页| 中文字幕日韩视频| 国产丝袜精品视频| 亚洲开心激情网| 亚洲免费av网址| 伦理中文字幕亚洲| 九色精品免费永久在线| 国产成一区二区| 98午夜经典影视| 国自在线精品视频| 国产成人精品视| 欧美亚洲国产日本| 亚洲视频在线观看视频| 国产成人精品日本亚洲专区61| 亚洲欧美激情在线视频| 欧美黑人国产人伦爽爽爽| 91精品中国老女人| www日韩中文字幕在线看| 91精品国产色综合久久不卡98| 国产欧美日韩亚洲精品| 欧美激情中文网| 日韩免费不卡av| 亚洲精品福利资源站| xvideos成人免费中文版| 国产欧美亚洲视频| 国产精品视频xxxx| 精品视频在线播放免| 国模精品视频一区二区| 日韩视频在线免费|