- regex [POSIX.1-2001準拠]
- ヘッダーファイル
-
#include <sys/types.h>
#include <regex.h>
-
- 構造体
-
typedef struct{
regoff_t rm_so; /* 次の最大マッチング部分の開始オフセット位置 */
regoff_t rm_eo; /* 終了オフセット位置 */
}regmatch_t;
-
- 関数プロトタイプ一覧
目次
ソースコード
[regex.c]
#include <stdio.h>
#include <stdlib.h> /* exit() */
#include <string.h> /* strncpy() */
#include <sys/types.h>
#include <regex.h> /* POSIX: */
/* regcomp(), regexec(), regfree(), regerror() */
#define MY_NMATCH 3
const char STRINGS = "123 4567.89 192.168.1.1 090-9876-5432" ;int main( int argc, char *argv[] )
{char buff[1024];
regex_t re;
int streg;
regmatch_t reg_match1, reg_match2[ MY_NMATCH ];
int offset, count;
int copy_sz, match_sz, buff_sz;
int idx, iRetRegexec;/*--- 引数チェック ---*/
if( argc != 2 ){
fprintf( stderr, "usage: %s <Regular_Expression>\n", argv[0] );
exit( 1 );
}/*--- 正規表現をコンパイル ---*/
if( ( streg = regcomp( &re, argv[1], REG_EXTENDED | REG_NEWLINE ) ) ){
regerror( streg, &re, buff, sizeof buff / sizeof( char ) );
fprintf( stderr, buff );
exit( 1 );
}buff_sz = ( ( sizeof buff ) / ( sizeof buff[0] ) ) - 1;
printf( "*** Global match ***\n" );
printf( " 0 1 2 3\n" );
printf( " 0123456789012345678901234567890123456789\n" );
printf( "STRING = ``%s''\n", STRINGS );/*--- 正規表現で検索実行 ---*/
for( offset=0, count=0
;
REG_NOMATCH != regexec( /* グローバルマッチ */
&re, /* preg : コンパイルされた正規表現 */
STRINGS + offset, /* string : 検索対象文字列 */
( sizeof reg_match1 ) / sizeof( regmatch_t ),
/* nmatch : */
®_match1, /* pmatch : マッチした位置の格納用配列 */
0 /* eflags : マッチング動作フラグ */
)
;
offset += reg_match1.rm_eo, count++
){
/*--- マッチした文字列をバッファにコピーする ---*/
match_sz = ( reg_match1.rm_eo - reg_match1.rm_so );
copy_sz = ( match_sz < buff_sz ) ? match_sz : buff_sz; /* 最小値を選択 */
strncpy( buff, ( STRINGS + offset + reg_match1.rm_so ), copy_sz );
buff[ copy_sz ] = '\0'; /* 終端文字を挿入しておく *//*--- 検索結果としてレポート ---*/
printf( "match: beg = %2ld, end = %2ld, ``%s''\n",
( long )( offset + reg_match1.rm_so ), ( long )( offset + reg_match1.rm_eo ), buff );
}/*--- レポート ---*/
if(count) printf( "match_count = `%d'\n\n", count );
else printf( "no match\n\n" );
printf( "*** Get up to %d backreferences ***\n", MY_NMATCH );
printf( " 0 1 2 3\n" );
printf( " 0123456789012345678901234567890123456789\n" );
printf( "STRING = ``%s''\n", STRINGS );/*--- 正規表現で検索実行 ---*/
iRetRegexec = regexec( &re, STRINGS, MY_NMATCH, reg_match2, 0 );
if( iRetRegexec != REG_NOMATCH ){
for( idx=0; idx<MY_NMATCH; idx++ ){
/*--- マッチした文字列をバッファにコピーする ---*/
match_sz = ( reg_match2[ idx ].rm_eo - reg_match2[ idx ].rm_so );
copy_sz = ( match_sz < buff_sz ) ? match_sz : buff_sz; /* 最小値を選択 */
strncpy( buff, ( STRINGS + reg_match2[ idx ].rm_so ), copy_sz );
buff[ copy_sz ] = '\0'; /* 終端文字を挿入しておく *//*--- 検索結果としてレポート ---*/
printf( "match: beg = %2ld, end = %2ld, ``%s''\n",
( long )( reg_match2[ idx ].rm_so ), ( long )( reg_match2[ idx ].rm_eo ), buff );
}
}
/*--- コンパイルした正規表現を解放 ---*/
regfree( &re );
return 0;
}
実行例
Cygwin 3.3.6-1, gcc (GCC) 11.3.0
$ gcc -Wall -O2 -o regex_cygwin regex.c
$
$ ./regex_cygwin.exe '[0-9]{1,3}'
*** Global match ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 0, end = 3, ``123''
match: beg = 5, end = 8, ``456''
match: beg = 8, end = 9, ``7''
match: beg = 10, end = 12, ``89''
match: beg = 14, end = 17, ``192''
match: beg = 18, end = 21, ``168''
match: beg = 22, end = 23, ``1''
match: beg = 24, end = 25, ``1''
match: beg = 27, end = 30, ``090''
match: beg = 31, end = 34, ``987''
match: beg = 34, end = 35, ``6''
match: beg = 36, end = 39, ``543''
match: beg = 39, end = 40, ``2''
match_count = `13'*** Get up to 3 backreferences ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 0, end = 3, ``123''
match: beg = -1, end = -1, ``''
match: beg = -1, end = -1, ``''
$
$ ## 「456」の次は「7」ではなく「567」とマッチさせたいかもしれない。
$ ## その場合は、サンプルコードのoffsetの加算部分を修正すれば良い。
$
$ ## 下記の正規表現では後方参照を使っている。
$ ./regex_cygwin.exe '([0-9]{2,3})-([0-9]{4}-[0-9]{4})'
*** Global match ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 27, end = 40, ``090-9876-5432''
match_count = `1'*** Get up to 3 backreferences ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 27, end = 40, ``090-9876-5432''
match: beg = 27, end = 30, ``090''
match: beg = 31, end = 40, ``9876-5432''
$
$ ./regex_cygwin.exe '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'
*** Global match ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 14, end = 25, ``192.168.1.1''
match_count = `1'*** Get up to 3 backreferences ***
0 1 2 3
0123456789012345678901234567890123456789
STRING = ``123 4567.89 192.168.1.1 090-9876-5432''
match: beg = 14, end = 25, ``192.168.1.1''
match: beg = -1, end = -1, ``''
match: beg = -1, end = -1, ``''
$