PCRE是一個用C語言編寫的正則表達式函數庫,它十分易用,同時功能也很強大,性能超過了POSIX正則表達式庫和一些經典的正則表達式庫,在使用PCRE庫時,首先肯定是需要安裝pcre的,不過一般的系統都會有自帶的PCRE庫。不過如果想使用最新版本的話,也可以自已下載一個安裝包。或者去官網上下載http://www.pcre.org/
PCRE的常用函數簡介
這裏只介紹了兩個常用的接口函數,另外的可通過PCRE源碼文檔進行了解。使用PCRE主要是使用下面介紹的這兩個函數。
pcre_compile
pcre *pcre_compile(const char *pattern, int options, const char **errptr, int *erroffset, const unsigned char *tableptr)
功能:將一個正則表達式編譯成一個內部表示,在匹配多個字符串時,可以加速匹配。其同pcre_compile2功能一樣只是缺少一個參數errorcodeptr。
參數說明
:
pattern 正則表達式
options 爲0,或者其他參數選項
errptr 出錯消息
erroffset 出錯位置
tableptr 指向一個字符數組的指針,可以設置爲空NULL。
pcre_exec
int pcre_exec(const pcre *code, const pcre_extra *extra, const char *subject, int length, int startoffset, int options, int *ovector, int ovecsize)
功能:使用編譯好的模式進行匹配,採用與Perl相似的算法,返回匹配串的偏移位置。
參數說明
:
code 編譯好的模式
extra 指向一個pcre_extra結構體,可以爲NULL
subject 需要匹配的字符串
length 匹配的字符串長度(Byte)
startoffset 匹配的開始位置
options 選項位
ovector 指向一個結果的整型數組
ovecsize 數組大小。
PCRE在C語言中實現正則表達式的解析
上述講了上面兩個PCRE函數的介紹,目的還是爲了能夠運用上,所以這裏就先講解下使用PCRE的過程。主要過程分三步走第一步編譯正則表達式;第二匹配正則表達式;第三步釋放正則表達式。
1.編譯正則表達式
爲了提高效率,在將一個字符串與正則表達式進行比較之前,首先要用pcre_compile() /pcre_compile2() 函數對它時行編譯,轉化成PCRE引擎能夠識別的結構(struct real_pcre)。
- 匹配正則表達式
一旦用函數pcre_compile() /pcre_compile2()成功地編譯了正則表達式,接下來就可以調用pcre_exec()函數完成模式匹配。根據正則表達式到指定的字符串中進行查找和匹配,並輸出匹配的結果。
- 釋放正則表達式
無論什麼時候,當不再需要已經編譯過的正則表達式時,都應該調用函數free()將其釋放,以免產生內在泄漏。
常用正則表達式
校驗數字的表達式
數字:^[0-9]*$
n位的數字:^\d{n}$
至少n位的數字:^\d{n,}$
m-n位的數字:^\d{m,n}$
零和非零開頭的數字:^(0|[1-9][0-9]*)$
非零開頭的最多帶兩位小數的數字:^([1-9][0-9]*)+(\.[0-9]{1,2})?$
帶1-2位小數的正數或負數:^(\-)?\d+(\.\d{1,2})$
正數、負數、和小數:^(\-|\+)?\d+(\.\d+)?$
有兩位小數的正實數:^[0-9]+(\.[0-9]{2})?$
有1~3位小數的正實數:^[0-9]+(\.[0-9]{1,3})?$
非零的正整數:^[1-9]\d*$ 或 ^([1-9][0-9]*){1,3}$ 或 ^\+?[1-9][0-9]*$
非零的負整數:^\-[1-9][]0-9"*$ 或 ^-[1-9]\d*$
非負整數:^\d+$ 或 ^[1-9]\d*|0$
非正整數:^-[1-9]\d*|0$ 或 ^((-\d+)|(0+))$
非負浮點數:^\d+(\.\d+)?$ 或 ^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$
非正浮點數:^((-\d+(\.\d+)?)|(0+(\.0+)?))$ 或 ^(-([1-9]\d*\.\d*|0\.\d*[1-9]\d*))|0?\.0+|0$
正浮點數:^[1-9]\d*\.\d*|0\.\d*[1-9]\d*$ 或 ^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$
負浮點數:^-([1-9]\d*\.\d*|0\.\d*[1-9]\d*)$ 或 ^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$
浮點數:^(-?\d+)(\.\d+)?$ 或 ^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$
校驗字符的表達式
漢字:^[\u4e00-\u9fa5]{0,}$
英文和數字:^[A-Za-z0-9]+$ 或 ^[A-Za-z0-9]{4,40}$
長度爲3-20的所有字符:^.{3,20}$
由26個英文字母組成的字符串:^[A-Za-z]+$
由26個大寫英文字母組成的字符串:^[A-Z]+$
由26個小寫英文字母組成的字符串:^[a-z]+$
由數字和26個英文字母組成的字符串:^[A-Za-z0-9]+$
由數字、26個英文字母或者下劃線組成的字符串:^\w+$ 或 ^\w{3,20}$
中文、英文、數字包括下劃線:^[\u4E00-\u9FA5A-Za-z0-9_]+$
中文、英文、數字但不包括下劃線等符號:^[\u4E00-\u9FA5A-Za-z0-9]+$ 或 ^[\u4E00-\u9FA5A-Za-z0-9]{2,20}$
可以輸入含有^%&',;=?$\"等字符:[^%&',;=?$\x22]+
禁止輸入含有~的字符:[^~\x22]+
校驗IPV4的地址合法性
下面使用PCRE庫函數的實現一個小例子,其功能是檢驗IPV4的地址合法性。
pcre_test.c
#include <stdio.h>
#include <stdlib.h>
#include <pcre.h>
#include <string.h>
#define OVERCOUNT 128
#define IP_NUM 20
/*
功能:校驗IPV4的地址合法性
輸出參數:地址合法則返回0,否則返回-1
*/
int check_if_ipv4_valid(char *ipv4)
{
//利用正則表達式去判斷IP地址是否合法
pcre *re = NULL;
int erroffset = 0;
const char *errptr=NULL;
int overtor[OVERCOUNT] = {0};
// 將要被編譯的字符串形式的正則表達
char ipv4_regular_expression[] = "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$";
if ((re = pcre_compile(ipv4_regular_expression,PCRE_CASELESS,&errptr,&erroffset,NULL)) ==NULL)
{
return -1;
}
if (pcre_exec(re,NULL,ipv4,strlen(ipv4),0,0,overtor,OVERCOUNT) > 0)
{
return 0;
}
pcre_free(re); // 編譯正則表達式re 釋放內存
return -1;
}
int main(int argc, char **argv)
{
char IP[IP_NUM];
printf("Input IPADDR\n");
fgets(IP,sizeof(IP),stdin);
if (0 == check_if_ipv4_valid(IP))
{
printf("IP legal\n");
}
else
{
printf("IP illegal\n");
}
}
編譯運行
從上面我們可以看到PCRE庫的使用相對簡單,首先執行pcre_compile()函數將模式編譯爲pcre數據結構,接下來就可以調用pcre_exec()函數完成模式匹配。根據正則表達式到指定的字符串中進行查找和匹配,並輸出匹配的結果。還有要記得編譯的時候要加上 -lpcre
總結
學習正則表達式的最好方法是從例子開始,理解例子之後再自己對例子進行修改,實驗。還有就是,如果你不覺得正則表達式很難讀寫的話,不妨找一種工具對正則表達式進行測試是否正確,這是很有必要的。例如:正則測試器 Regex Tester
歡迎關注公衆號【程序猿編碼】,添加本人微信號(17865354792),回覆:領取學習資料。或者回復:進入技術交流羣。網盤資料有如下:
參考:《菜鳥教程-正則表達式》