筆記整理——Linux下C語言正則表達式


Linux下C語言正則表達式使用詳解 - Google Chrome (2013/5/2 16:40:37)

Linux下C語言正則表達式使用詳解

2012年6月6日 Neal 627 views 發表評論 閱讀評論

標准的C和C++都不支持正則表達式,但有一些函數庫可以輔助C/C++程序員完成這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫。

C語言處理正則表達式常用的函數有regcomp()、regexec()、regfree()和regerror(),一般分為三個步驟,如下所示:

C語言中使用正則表達式一般分為三步:
1. 編譯正則表達式 regcomp()
2. 匹配正則表達式 regexec()
3. 釋放正則表達式 regfree()

下邊是對三個函數的詳細解釋

1. int regcomp (regex_t *compiled, const char *pattern, int cflags)
這個函數把指定的正則表達式pattern編譯成一種特定的數據格式compiled,這樣可以使匹配更有效。函數regexec 會使用這個數據在目標文本串中進行模式匹配。執行成功返回0。

參數說明:
①regex_t 是一個結構體數據類型,用來存放編譯后的正則表達式,它的成員re_nsub 用來存儲正則表達式中的子正則表達式的個數,子正則表達式就是用圓括號包起來的部分表達式。
②pattern 是指向我們寫好的正則表達式的指針。
③cflags 有如下4個值或者是它們或運算(|)后的值:
REG_EXTENDED 以功能更加強大的擴展正則表達式的方式進行匹配。
REG_ICASE 匹配字母時忽略大小寫。
REG_NOSUB 不用存儲匹配后的結果。
REG_NEWLINE 識別換行符,這樣'$'就可以從行尾開始匹配,'^'就可以從行的開頭開始匹配。

2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)
當我們編譯好正則表達式后,就可以用regexec 匹配我們的目標文本串了,如果在編譯正則表達式的時候沒有指定cflags的參數為REG_NEWLINE,則默認情況下是忽略換行符的,也就是把整個文本串當作一個字符串處理。執行成功返回0。
regmatch_t 是一個結構體數據類型,在regex.h中定義:
typedef struct
{
regoff_t rm_so;
regoff_t rm_eo;
} regmatch_t;
成員rm_so 存放匹配文本串在目標串中的開始位置,rm_eo 存放結束位置。該函數雖然以regmatch_t數組的形式定義了參數,但是實際上regexec()函數只能匹配到一個,讓人誤解啊,特別注明一下。

參數說明:
①compiled 是已經用regcomp函數編譯好的正則表達式。
②string 是目標文本串。
③nmatch 是regmatch_t結構體數組的長度。
④matchptr regmatch_t類型的結構體數組,存放匹配文本串的位置信息。
⑤eflags 有兩個值
REG_NOTBOL 按我的理解是如果指定了這個值,那么'^'就不會從我們的目標串開始匹配。總之我到現在還不是很明白這個參數的意義;
REG_NOTEOL 和上邊那個作用差不多,不過這個指定結束end of line。

3. void regfree (regex_t *compiled)
當我們使用完編譯好的正則表達式后,或者要重新編譯其他正則表達式的時候,我們可以用這個函數清空compiled指向的regex_t結構體的內容,請記住,如果是重新編譯的話,一定要先清空regex_t結構體

4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)
當執行regcomp 或者regexec 產生錯誤的時候,就可以調用這個函數而返回一個包含錯誤信息的字符串。

參數說明:
①errcode 是由regcomp 和 regexec 函數返回的錯誤代號。
②compiled 是已經用regcomp函數編譯好的正則表達式,這個值可以為NULL。
③buffer 指向用來存放錯誤信息的字符串的內存空間。
④length 指明buffer的長度,如果這個錯誤信息的長度大於這個值,則regerror 函數會自動截斷超出的字符串,但他仍然會返回完整的字符串的長度。所以我們可以用如下的方法先得到錯誤字符串的長度。

size_t length = regerror (errcode, compiled, NULL, 0);

下邊是一個連續查找文本中匹配字符串的例子:

#include <stdio.h>
#include <string.h>
#include <regex.h>
 
// 提取子串
char* getsubstr(char *s, regmatch_t *pmatch)
{
	static char buf[100] = {0};
	memset(buf, 0, sizeof(buf));
	memcpy(buf, s+pmatch->rm_so, pmatch->rm_eo - pmatch->rm_so);
 
	return buf;
}
 
int main(void)
{
	regmatch_t pmatch;
	regex_t reg;
	const char *pattern = "[a-z]+";		// 正則表達式
	char buf[] = "HELLOsaiYear2012@gmail.com";	// 待搜索的字符串
 
	regcomp(&reg, pattern, REG_EXTENDED);	//編譯正則表達式
	int offset = 0;
 	while(offset < strlen(buf))
	{
		int status = regexec(&reg, buf + offset, 1, &pmatch, 0);
		/* 匹配正則表達式,注意regexec()函數一次只能匹配一個,不能連續匹配,網上很多示例並沒有說明這一點 */
		if(status == REG_NOMATCH)
			printf("No Match\n");
		else if(pmatch.rm_so != -1)
		{
			printf("Match:\n");
			char *p = getsubstr(buf + offset, &pmatch);
 			printf("[%d, %d]: %s\n", offset + pmatch.rm_so + 1, offset + pmatch.rm_eo, p);
		}
		offset += pmatch.rm_eo;
	}
	regfree(&reg);		//釋放正則表達式
 
	return 0;
}

正則表達式梳理(unix) - aten_xie的專欄 - 博客頻道 - CSDN.NET - Google Chrome (2013/4/16 18:14:01)

 

正則表達式梳理(unix)

分類: SHELL   945人閱讀   評論(0)   收藏   舉報

   正則表達式(regular experience RE)是一種字符模式,用於在查找過程中匹配指定的字符。在大多數程序中,正則表達式都被置於兩個正斜杠之間。例如:/test/ 就是由正斜杠界定的正則表達式,它將匹配被查找的行中任何位置出現的相同模式。

   正則表達式元字符

   元字符是這樣一類字符,它們表達的是不同於字面本身的含義。正則表達式元字符是由各種執行模式匹配操作的程序來解析,例如:sed、grep、awk等。

   常用正則表達式的元字符如下:

元字符 功能 實例 匹配結果 備注
^ 行首定位符 /^test/ 匹配所有以test開頭的行 空格、TAB等也是作為字符進行匹配的。
$ 行尾定位符 /test$/ 匹配所有以test結尾的行  
.  (點) 匹配除“/n”之外的任何單個字符 /t..t/ 匹配包含一個t,后跟兩個字符,在跟一個t的行。 任意單個字符包含空格和TAB鍵。 
即:“t  t” 也是滿足匹配條件的。 
若要匹配包括“/n”在內的任意字符,請使用諸如“[/s/S]”之類的模式。
* 零次或多次匹配前面的字符或子表達式 /t*est/ 匹配包含0個或者多個t后跟est的行。可以匹配:est、test、ttest  
+ 一次或多次匹配前面的字符或子表達式 /t+est/ 匹配包含1個或者多個t后跟est的行。可以匹配:test、ttest。字符串“est”則無法進行匹配了。  
? 零次或者一次匹配前面的字符串或者子表達式 /t?est/ 匹配包含0個或者1個t后跟est的行。可以匹配:test、est。 ttest 也是符合匹配標准的,因為ttest字符串中包含整個test。
當此字符緊隨任何其他限定符(*、+、?、{n}、{n,}、{n,m})之后時,匹配模式是“非貪心的”。“非貪心的”模式匹配搜索到的、盡可能短的字符串,而默認的“貪心的”模式匹配搜索到的、盡可能長的字符串。例如,在字符串“oooo”中,“o+?”只匹配單個“o”,而“o+”匹配所有“o”。
[] 匹配一組字符中的任一個 /[Tt]est/ 匹配包含Test或者test行  
[x-y] 匹配指定范圍內的一個字符 /[A-Z]est/ 匹配后面跟着est的一個A至Z之間的字符。 [0-9]:用來匹配任意數字 
[A-Za-z]:用來匹配任意字母
[^] 匹配不在指定組內的字符 /[^A-Z]/ 匹配不在范圍A至Z之間的任一個字符  
/ 用來轉義元字符 /test/*/ 匹配包含test,后面跟一個*號的所有行。 ////用來匹配“/”符號自身
/< 詞首定位符 // 匹配包含以love開頭的詞的行。如:love、lover vi和grep支持
/> 詞尾定位符 /love/>/ 匹配包含以love結尾的詞的行。 
如:aalove
vi和grep支持
/(pattern/) 匹配模式pattern,並將之存儲在寄存器中,供之后使用。 //(love/)able /1r/ 最多可以使用9個標簽,模式中最左邊的標簽是第一個。例如:模式love被保存為標簽1,用/1表示。左邊這個例子中,查找串是一個loveable 后跟 lover的長串。 sed、vi、grep支持。 
例如: 
sed “s//(love/)//1able/” 功能是將文件中的love替換成loveable。
x/{m/} 或 
x/{m,/} 或 
x/{m,n/}
字符x的重復出現; 
m次,至少m次,至少m次且不超過n次。
o/{5,10/} 匹配包含5-10個連續的字母o的行。 vi和grep支持

   grep支持的正則表達式元字符

元字符 功能 實例 匹配結果 備注
^ 行首定位符 grep “^test” datafile 打印所有以test開頭的行  
$ 行尾定位符 grep “test$” datafile 打印所有以test結尾的行  
.  (點) 匹配除“/n”之外的任何單個字符 /t..t/ 匹配包含一個t,后跟兩個字符,在跟一個t的行。  
* 零次或多次匹配前面的字符或子表達式 /t*est/ 匹配包含0個或者多個t后跟est的行。可以匹配:est、test、ttest  
[] 匹配一組字符中的任一個 /[Tt]est/ 匹配包含Test或者test行  
[^] 匹配不在指定組內的字符 /[^A-Z]/ 匹配不在范圍A至Z之間的任一個字符  
/< 詞首定位符 // 匹配包含以love開頭的詞的行。如:love、lover vi和grep支持
/> 詞尾定位符 /love/>/ 匹配包含以love結尾的詞的行。 
如:aalove
vi和grep支持
/(pattern/) 匹配模式pattern,並將之存儲在寄存器中,供之后使用。 //(love/)able /1r/ 最多可以使用9個標簽,模式中最左邊的標簽是第一個。例如:模式love被保存為標簽1,用/1表示。左邊這個例子中,查找串是一個loveable 后跟 lover的長串。 sed、vi、grep支持。 
例如: 
sed “s//(love/)//1able/” 功能是將文件中的love替換成loveable。
x/{m/} 或 
x/{m,/} 或 
x/{m,n/}
字符x的重復出現; 
m次,至少m次,至少m次且不超過n次。
o/{5,10/} 匹配包含5-10個連續的字母o的行。

C語言正則表達式詳解 regcomp() regexec() regfree()詳解_正則表達式教程 - Google Chrome (2013/4/10 12:09:15)

C語言中嵌入正則表達式

標准的C和C++都不支持正則表達式,但有一些函數庫可以輔助C/C++程序員完成這一功能,其中最著名的當數Philip Hazel的Perl-Compatible Regular Expression庫,許多Linux發行版本都帶有這個函數庫。

C語言處理正則表達式常用的函數有regcomp()、regexec()、regfree()和regerror(),一般分為三個步驟,如下所示:

C語言中使用正則表達式一般分為三步:
  1. 編譯正則表達式 regcomp()
  2. 匹配正則表達式 regexec()
  3. 釋放正則表達式 regfree()


下邊是對三個函數的詳細解釋

1、int regcomp (regex_t *compiled, const char *pattern, int cflags)
這個函數把指定的正則表達式pattern編譯成一種特定的數據格式compiled,這樣可以使匹配更有效。函數regexec 會使用這個數據在目標文本串中進行模式匹配。執行成功返回0。  

參數說明:
①regex_t 是一個結構體數據類型,用來存放編譯后的正則表達式,它的成員re_nsub 用來存儲正則表達式中的子正則表達式的個數,子正則表達式就是用圓括號包起來的部分表達式。
②pattern 是指向我們寫好的正則表達式的指針。
③cflags 有如下4個值或者是它們或運算(|)后的值:
REG_EXTENDED 以功能更加強大的擴展正則表達式的方式進行匹配。
REG_ICASE 匹配字母時忽略大小寫。
REG_NOSUB 不用存儲匹配后的結果。
REG_NEWLINE 識別換行符,這樣'$'就可以從行尾開始匹配,'^'就可以從行的開頭開始匹配。

2. int regexec (regex_t *compiled, char *string, size_t nmatch, regmatch_t matchptr [], int eflags)
當我們編譯好正則表達式后,就可以用regexec 匹配我們的目標文本串了,如果在編譯正則表達式的時候沒有指定cflags的參數為REG_NEWLINE,則默認情況下是忽略換行符的,也就是把整個文本串當作一個字符串處理。執行成功返回0。
regmatch_t 是一個結構體數據類型,在regex.h中定義:             
typedef struct
{
   regoff_t rm_so;
   regoff_t rm_eo;
} regmatch_t;
成員rm_so 存放匹配文本串在目標串中的開始位置,rm_eo 存放結束位置。通常我們以數組的形式定義一組這樣的結構。因為往往我們的正則表達式中還包含子正則表達式。數組0單元存放主正則表達式位置,后邊的單元依次存放子正則表達式位置。

參數說明:
①compiled 是已經用regcomp函數編譯好的正則表達式。
②string 是目標文本串。
③nmatch 是regmatch_t結構體數組的長度。
④matchptr regmatch_t類型的結構體數組,存放匹配文本串的位置信息。
⑤eflags 有兩個值
REG_NOTBOL 按我的理解是如果指定了這個值,那么'^'就不會從我們的目標串開始匹配。總之我到現在還不是很明白這個參數的意義;
REG_NOTEOL 和上邊那個作用差不多,不過這個指定結束end of line。

3. void regfree (regex_t *compiled)
當我們使用完編譯好的正則表達式后,或者要重新編譯其他正則表達式的時候,我們可以用這個函數清空compiled指向的regex_t結構體的內容, 請記住,如果是重新編譯的話,一定要先清空regex_t結構體

4. size_t regerror (int errcode, regex_t *compiled, char *buffer, size_t length)
當執行regcomp 或者regexec 產生錯誤的時候,就可以調用這個函數而返回一個包含錯誤信息的字符串。

參數說明:
①errcode 是由regcomp 和 regexec 函數返回的錯誤代號。
②compiled 是已經用regcomp函數編譯好的正則表達式,這個值可以為NULL。
③buffer 指向用來存放錯誤信息的字符串的內存空間。
④length 指明buffer的長度,如果這個錯誤信息的長度大於這個值,則regerror 函數會自動截斷超出的字符串,但他仍然會返回完整的字符串的長度。所以我們可以用如下的方法先得到錯誤字符串的長度。

size_t length = regerror (errcode, compiled, NULL, 0);

下邊是一個匹配Email例子,按照上面的三步就可以。


下面的程序負責從命令行獲取正則表達式,然后將其運用於從標准輸入得到的每行數據,並打印出匹配結果。
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>

/* 取子串的函數 */
static char* substr(const char*str,
unsigned start, unsigned end)
{
  unsigned n = end - start;
  static char stbuf[256];
  strncpy(stbuf, str + start, n);
  stbuf[n] = 0;
  return stbuf;
}

/* 主程序 */
int main(int argc, char** argv)
{
  char * pattern;
  int x, z, lno = 0, cflags = 0;
  char ebuf[128], lbuf[256];
  regex_t reg;
  regmatch_t pm[10];
  const size_t nmatch = 10;
  /* 編譯正則表達式*/
  pattern = argv[1];
  z = regcomp(?, pattern, cflags);
  if (z != 0){
    regerror(z, ?, ebuf, sizeof(ebuf));
    fprintf(stderr, "%s: pattern '%s' \n",ebuf, pattern);
    return 1;
  }
  /* 逐行處理輸入的數據 */
  while(fgets(lbuf, sizeof(lbuf), stdin))
  {
    ++lno;
    if ((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')
    lbuf[z - 1] = 0;
    /* 對每一行應用正則表達式進行匹配 */
    z = regexec(?, lbuf, nmatch, pm, 0);
    if (z == REG_NOMATCH) continue;
    else if (z != 0) {
      regerror(z, ?, ebuf, sizeof(ebuf));
      fprintf(stderr, "%s: regcom('%s')\n", ebuf, lbuf);
      return 2;
    }
    /* 輸出處理結果 */
    for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)
    {
      if (!x) printf("%04d: %s\n", lno, lbuf);
      printf(" $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));
    }
  }
  /* 釋放正則表達式 */
  regfree(?);
  return 0;
}

執行下面的命令可以編譯並執行該程序:
# gcc regexp.c -o regexp
# ./regexp 'regex[a-z]*' < regexp.c
0003: #include <regex.h>
$0='regex'
0027: regex_t reg;
$0='regex'
0054: z = regexec(?, lbuf, nmatch, pm, 0);
$0='regexec'

常用正則表達式-月光博客 - Google Chrome (2013/4/10 10:09:16)

正則表達式用於字符串處理、表單驗證等場合,實用高效。現將一些常用的表達式收集於此,以備不時之需。

匹配中文字符的正則表達式: [\u4e00-\u9fa5]
評注:匹配中文還真是個頭疼的事,有了這個表達式就好辦了

匹配雙字節字符(包括漢字在內):[^\x00-\xff]
評注:可以用來計算字符串的長度(一個雙字節字符長度計2,ASCII字符計1)

匹配空白行的正則表達式:\n\s*\r
評注:可以用來刪除空白行

匹配HTML標記的正則表達式:<(\S*?)[^>]*>.*?</\1>|<.*? />
評注:網上流傳的版本太糟糕,上面這個也僅僅能匹配部分,對於復雜的嵌套標記依舊無能為力

匹配首尾空白字符的正則表達式:^\s*|\s*$
評注:可以用來刪除行首行尾的空白字符(包括空格、制表符、換頁符等等),非常有用的表達式

匹配Email地址的正則表達式:\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*
評注:表單驗證時很實用

匹配網址URL的正則表達式:[a-zA-z]+://[^\s]*
評注:網上流傳的版本功能很有限,上面這個基本可以滿足需求

匹配帳號是否合法(字母開頭,允許5-16字節,允許字母數字下划線):^[a-zA-Z][a-zA-Z0-9_]{4,15}$
評注:表單驗證時很實用

匹配國內電話號碼:\d{3}-\d{8}|\d{4}-\d{7}
評注:匹配形式如 0511-4405222 或 021-87888822

匹配騰訊QQ號:[1-9][0-9]{4,}
評注:騰訊QQ號從10000開始

匹配中國郵政編碼:[1-9]\d{5}(?!\d)
評注:中國郵政編碼為6位數字

匹配身份證:\d{15}|\d{18}
評注:中國的身份證為15位或18位

匹配ip地址:\d+\.\d+\.\d+\.\d+
評注:提取ip地址時有用

匹配特定數字:
^[1-9]\d*$    //匹配正整數
^-[1-9]\d*$   //匹配負整數
^-?[1-9]\d*$   //匹配整數
^[1-9]\d*|0$  //匹配非負整數(正整數 + 0)
^-[1-9]\d*|0$   //匹配非正整數(負整數 + 0)
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$   //匹配正浮點數
^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$  //匹配負浮點數
^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$  //匹配浮點數
^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$   //匹配非負浮點數(正浮點數 + 0)
^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$  //匹配非正浮點數(負浮點數 + 0)
評注:處理大量數據時有用,具體應用時注意修正

匹配特定字符串:
^[A-Za-z]+$  //匹配由26個英文字母組成的字符串
^[A-Z]+$  //匹配由26個英文字母的大寫組成的字符串
^[a-z]+$  //匹配由26個英文字母的小寫組成的字符串
^[A-Za-z0-9]+$  //匹配由數字和26個英文字母組成的字符串
^\w+$  //匹配由數字、26個英文字母或者下划線組成的字符串
評注:最基本也是最常用的一些表達式

原載地址:http://lifesinger.3322.org/myblog/?p=185

 

 

本文章要提供的這些表達式是url 卡號 數字 郵編 QQ號 整數 英文 中文正則代碼哦,下面我們來一一注明吧。

Url : /^http://[A-Za-z0-9]+.[A-Za-z0-9]+[/=?%-&_~`@[]':+!]*([^<>""])*$/, //地址正則


IdCard : /^d{15}(d{2}[A-Za-z0-9])?$/, //卡號正則


Currency : /^d+(.d+)?$/,


Number : /^d+$/, //數字


Zip : /^[1-9]d{5}$/, //郵編


QQ : /^[1-9]d{4,8}$/, //QQ正則


Integer : /^[-+]?d+$/,


Double : /^[-+]?d+(.d+)?$/,


English : /^[A-Za-z]+$/, //英語


Chinese : /^[u0391-uFFE5]+$/, 漢字


Username : /^[a-z]w{3,}$/i,


UnSafe : /^(([A-Z]*|[a-z]*|d*|[-_~!@#$%^&*.()[]{}<>?\/'"]*)|.{0,5})$|s/,

 

linux C regex正則表達式函數庫 - crocodile的記錄空間 - 51CTO技術博客 - Google Chrome (2013/4/1 13:53:29)

linux C regex正則表達式函數庫
2012-08-20 00:03:55
標簽: linux 編程
C中的正則表達式如何實現呢,以regex系列函數來簡要說明:
 
標准的linux c與c++不支持正則表達式;
以POSIX函數庫中的Regex系列函數來說明在Linux c下如何使用正則表達式:
 
1、編譯正則表達式:
 
      Regcomp函數,生成regex_t數據結構;
 
      int Regcomp(regex_t *preg, const char *regex, int cflags);
        參數說明:
 
            preg:用來保存編譯的結果; 
            regex:字符串,表示被編譯的正則表達式;
            cflags:編譯開關控制細節;
                     REG_EXTEND代表使用擴展正則表達式模式;
                     REG_ICASE表示對規則中字符串不區分大小寫;
                     REG_NOSUB只檢查是否有符合規則的子串
 
2、匹配正則表達式:
 
           利用regcomp生成的數據結構regex_t *preg 調用regexec()函數完成模式匹配:
           int regexec(
                                    const regex_t *preg, 
                                    const char *string, 
                                    size_t match,
                                    regmatch_t pmatch[],
                                    int eflags
                                    );
  typedef struct {
  regoff_t rm_so;
  regoff_t rm_eo;
  } regmatch_t;
 
        參數說明:
 
            preg:用來編譯后的模式匹配數據結構regex_t 常量; 
            string:字符串,表示被匹配的字符串;
            nmatch:被匹配的個數;
            pmatch:匹配的結果數組;
                        rm_so 表示滿足規則的子串在string中的起始偏移量
                        rm_eo 表示滿足規則的子串在string中的后續偏移量
            eflags:匹配的特性
                        REG_NOTBOL 是否是第一行
                        REG_NOTEOL 是否是最后一行
 
 
3、報告錯誤信息

size_t regerror(int errcode, const regex_t *preg, char *errbuf, size_t errbuf_size);

 參數說明:
 
            errcode:來自regcomp及regexec函數的錯誤代碼; 
            preg:regcomp編譯結果;
            errbuf:緩沖區的錯誤信息字符串;
            errbuf_size:緩存區的錯誤信息字符串長度; 
 

4、釋放正則表達式:

void regfree(regex_t *preg);

               無返回結果,釋放regcomp編譯的regex_t指針;

5、正則表達式框架:
int mymatch(char *buf)
{
    const char *regex = "href=\"[^ >]*\"";
      regex_t preg;
    const size_t nmatch = 10;
      regmatch_t pm[nmatch];
    if ( regcomp(&preg, regex, 0) != 0) {    /*編譯正則表達式失敗 */
        perror("regcomp");
        exit(1);
    }
    int z, i;
      z = regexec(&preg, buf, nmatch, pm, 0);
    if (z == REG_NOMATCH)/*無匹配項 */  
    {     
        return 0;
    }  
    else/*有匹配的超鏈接 */
    {         
        for (i = 0;   i < nmatch && pm[i].rm_so != -1;  ++i)/*把超鏈接都提取出*/
        {
            /*對匹配鏈接的操作*/
        }     
     
    }
      regfree(&preg);/*釋放正則表達式*/
}
6、正則表達式實例:

 

#include <stdio.h>

#include <sys/types.h>

#include <regex.h>

#include <string.h>

 

static char* substr(const char*str, unsigned start, unsigned end)

{

  unsigned n = end - start;

  static char stbuf[256];

  strncpy(stbuf, str + start, n);

  stbuf[n] = 0; 

  return stbuf;

}

 

int main(int argc, char** argv)

{

  char * pattern;

  int x, z, lno = 0, cflags = 0;

  char ebuf[128], lbuf[256];

  regex_t reg;

  regmatch_t pm[10];

  const size_t nmatch = 10;

 

  pattern = argv[1];

  z = regcomp(&reg, pattern, cflags);

  if (z != 0)

  {

    regerror(z, &reg, ebuf, sizeof(ebuf));

    fprintf(stderr, "%s: pattern '%s' \n", ebuf, pattern);

    return 1;

  }

 

  while(fgets(lbuf, sizeof(lbuf), stdin))

   {

    ++lno;

    if ((z = strlen(lbuf)) > 0 && lbuf[z-1] == '\n')

      lbuf[z - 1] = 0;

   

    z = regexec(&reg, lbuf, nmatch, pm, 0);

    if (z == REG_NOMATCH) continue;

    else if (z != 0)

    {

      regerror(z, &reg, ebuf, sizeof(ebuf));

      fprintf(stderr, "%s: regcom('%s')\n", ebuf, lbuf);

      return 2;

    }

   

    for (x = 0; x < nmatch && pm[x].rm_so != -1; ++ x)

    {

      if (!x) printf("d: %s\n", lno, lbuf);

      printf("  $%d='%s'\n", x, substr(lbuf, pm[x].rm_so, pm[x].rm_eo));

    }

  }

 

  regfree(&reg);

  return 0;

}



編譯執行

 

bitwangbin@mac:~/code/c/regex > gcc regexp.c -o regexp

bitwangbin@mac:~/code/c/regex > ./regexp  'regex[a-z]*' < regexp.c

0003: #include <regex.h>;

  $0='regex'

0020:   regex_t reg;

  $0='regex'

0037:     z = regexec(&reg, lbuf, nmatch, pm, 0);

  $0='regexec'






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM