C言語で正規表現を使う
13275 ワード
回転:http://blog.chinaunix.net/uid-479984-id-2114941.html
良いプログラマはDBとReglar Expressionを使うプログラマーだと言われていますが、どちらが重要なのかが分かります.正規表現は仕事の効率を高めるツールであり、LinuxにREの特性を持つさまざまなツールを使ったことがある人はきっと深い感銘を受けます.REは多くの言語でサポートされています.もちろん一番多く使われているのは脚本です.しかし、C言語でREを使うのは多くないですが、時には役に立ちます.最近は他の人がこれを言っているのを見ましたので、資料を調べて自分の体験を加えて、C言語でのREの応用を説明します.C言語自体はRE特性を持っていませんが、多くのライブラリがあります.Linuxでは、regex.hが提供するライブラリを使いやすいです.まずコードを貼ります.REはC言語でどうやって使いますか?
良いプログラマはDBとReglar Expressionを使うプログラマーだと言われていますが、どちらが重要なのかが分かります.正規表現は仕事の効率を高めるツールであり、LinuxにREの特性を持つさまざまなツールを使ったことがある人はきっと深い感銘を受けます.REは多くの言語でサポートされています.もちろん一番多く使われているのは脚本です.しかし、C言語でREを使うのは多くないですが、時には役に立ちます.最近は他の人がこれを言っているのを見ましたので、資料を調べて自分の体験を加えて、C言語でのREの応用を説明します.C言語自体はRE特性を持っていませんが、多くのライブラリがあります.Linuxでは、regex.hが提供するライブラリを使いやすいです.まずコードを貼ります.REはC言語でどうやって使いますか?
1 #include<stdio.h>
2 #include<sys/types.h>
3 #include<regex.h>
4 #include<memory.h>
5 #include<stdlib.h>
6
7 int main(){
8
9 char *bematch = "[email protected]";
10 char *pattern = "h{3,10}(.*)@.{5}.(.*)";
11 char errbuf[1024];
12 char match[100];
13 regex_t reg;
14 int err,nm = 10;
15 regmatch_t pmatch[nm];
16
17 if(regcomp(®,pattern,REG_EXTENDED) < 0){
18 regerror(err,®,errbuf,sizeof(errbuf));
19 printf("err:%s
",errbuf);
20 }
21
22 err = regexec(®,bematch,nm,pmatch,0);
23
24 if(err == REG_NOMATCH){
25 printf("no match
");
26 exit(-1);
27 }else if(err){
28 regerror(err,®,errbuf,sizeof(errbuf));
29 printf("err:%s
",errbuf);
30 exit(-1);
31 }
32
33 for(int i=0;i<10 && pmatch[i].rm_so!=-1;i++){
34 int len = pmatch[i].rm_eo-pmatch[i].rm_so;
35 if(len){
36 memset(match,'\0',sizeof(match));
37 memcpy(match,bematch+pmatch[i].rm_so,len);
38 printf("%s
",match);
39 }
40 }
41 return 0;
42 }
メールアドレスが私の提供したpatternに合うかどうかを確認したいです.このメールアドレスは[email protected] paternは"h{3,10}(.*)@.{5}.(.*)"
3 h ( ) @, 5 . , ( ),
[email protected]
ericchd
com
, , , , pattern 。 , C RE UNIX RE :
、\{\} \(\) {} (), C
、. , UNIX RE \., ? *
レゲックスの使用には以下のいくつかの関数が必要です.(/usr/include/regex.hファイルで定義) 要点 regcomp (regextu *comppiled、 コンサート char *pattern 要点 cflags 要点 regexec (regextu *comppiled、 char *ストリングス sizaut nmatch、 regmatichut match ptr [] 要点 eflags) void reg free (regextu *comppiled) size_t レギュレータ (int errceode レゲックス *comppiled、 char *ブザー、 sizaut length 1.int regcomp (regextu *comppiled、 コンサート char *pattern 要点 cflags この関数は指定された規則式patternを特定のデータフォーマットcompledにコンパイルして、マッチングをより効果的にすることができます.関数regexec このデータを使って目標文にいます. この列でモードマッチングを行います.実行成功は0に戻ります. レゲックス.t は、コンパイルされた規則式を保存するために使用される構造体データの種類で、そのメンバーはre_です.nsub 規則式のサブルール表現の数を格納するために使用されます.サブルール表現は、丸かっこで囲む部分表現です. pattern 私たちが作成した規則表現の指針です. cflags 次の4つの値またはそれらまたは演算後の値があります. REG_EXTENDED より強力な機能を持つ拡張規則式の方法で一致した. REG_ICASE 文字にマッチするときは、大文字と小文字を無視します. REG_NOSUB マッチした結果は記憶されません. REG_NEWLINE 改行記号を識別します.このように'$は行末からマッチします.'^'は行の先頭からマッチします. 2. 要点 regexec (regextu *comppiled、 char *ストリングス sizaut nmatch、 regmatichut match ptr [] int eflags) ルール表現をコンパイルしたら、regexecが使えます. 私たちのターゲットテキストにマッチしました.ルール表現をコンパイルする時にcflagsを指定していないパラメータがREG_です.NEWLINEではデフォルトでは改行を無視します.つまり文字列全体を文字列として処理します.実行成功は0に戻ります. regmatch_t は、構造体のデータの種類は、メンバーrm_です.そ マッチする文字列をターゲットの列の開始位置に保存します.eo 預かり終了ビット 買う.このような構造のセットは一般に配列として定義される.しばしば私たちの規則式にはサブルール表現も含まれているからです.配列0ユニットは、プライマリ規則式の位置を格納し、後のユニットはサブルール式の位置を順次保存します. compled は既にregcomp関数でコンパイルされている規則式です. ストリングス は、ターゲットテキスト列です. nmatch regmatchですt構造体配列の長さ. match ptr regmatch_tタイプの構造体配列は、テキスト列にマッチする位置情報を格納します. eflags 二つの値があります REG_NOTB OL 私の理解では、この値を指定したら、'^'は私達の目標列からマッチングしないと思います.つまり、私はまだこのパラメータの意味がよく分かりません. 原文は以下の通りです If. this ビット is セット then the Beginning-off-line operator ドスン match the beginning 保存先 the ストリングス (presumably because it not the beginning 保存先 a. ライン not セット then the Beginning-off-line operator はい match the beginning 保存先 the string. REG_NOTEOL 上のような役割ですが、この指定はendを終了します. 保存先 ライン. 3. void reg free (regextu *comppiled) コンパイルされた規則式を使って、あるいは他の規則式をコンパイルし直すときは、この関数でクリアできます. compledが指すregex_t構造体の内部 再コンパイルの場合は、必ず先にクリアしてください.t構造体 4. size_t レギュレータ (int errceode レゲックス *comppiled、 char *ブザー、 sizaut length regcompを実行する時 もしくはregexec エラーが発生した場合、この関数を呼び出してエラー情報を含む文字列を返します. errceode regcompからです 和 regexec 関数が返したエラーコードです. compled は、regcomp関数でコンパイルされている規則式です.この値はNULLです. ブザー エラー情報を保存する文字列のメモリ空間を指します. length このエラー情報の長さがこの値よりも長い場合、ブレザーの長さを指定します. 関数は自動的に文字列を切断しますが、完全な文字列の長さを返します.したがって、私たちは以下の方法でまずエラー文字列の長さを得ることができます. size_t length = レギュレータ (errceode、 comppiled、 NULL 0) regexは簡単に使用できますが、正規表現への対応があまり強くないため、中国語の処理にも問題があります.(試験後にviの正規表現を参照して作成した例があります.)PCREは別の選択PCREです. (http://www.pcre.org)いい資料があります.http://midatl.radford.edu/docs/C/Pattern-Matching.html#Pattern-Match ing