Linux下C語言正則表達式使用詳解 - Google Chrome (2013/5/2 16:40:37)
Linux下C語言正則表達式使用詳解
正則表達式梳理(unix) - aten_xie的專欄 - 博客頻道 - CSDN.NET - Google Chrome (2013/4/16 18:14:01)
正則表達式(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語言處理正則表達式常用的函數有regcomp()、regexec()、regfree()和regerror(),一般分為三個步驟,如下所示:
- C語言中使用正則表達式一般分為三步:
-
- 編譯正則表達式 regcomp()
- 匹配正則表達式 regexec()
- 釋放正則表達式 regfree()
下邊是對三個函數的詳細解釋
這個函數把指定的正則表達式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)
{
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);/*釋放正則表達式*/
}
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
#include <string.h>
static char* substr(const char*str, unsigned start, unsigned end)
{
}
int main(int argc, char** argv)
{
{
{
{
{
}
編譯執行
bitwangbin@mac:~/code/c/regex > gcc regexp.c -o regexp
bitwangbin@mac:~/code/c/regex > ./regexp
0003: #include <regex.h>;
0020:
0037:
