Created
August 25, 2013 13:48
-
-
Save brokendish/6333931 to your computer and use it in GitHub Desktop.
xml_CSV_Getlib.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <libxml/tree.h> | |
#include <libxml/parser.h> | |
#include <libxml/xpath.h> | |
#include <regex.h> | |
#include "xml_CSV_Getlib.h" | |
/* デバグ用定義 */ | |
/*#define DEBUG1*/ | |
/* | |
-------------------------------------------------------------------- | |
気象庁のMXLファイルから必要な部分を抽出してCSVファイルにする | |
対応するXMLデータの入力方式 | |
・XMLデータのメモリからの入力(電文) パラメータ(opt=0)を指定時 | |
・XMLファイルの場所を指定しての入力 パラメータ(opt=1)を指定時 | |
・標準入力からのXML入力 パラメータ(opt=2)を指定時 | |
作成中 | |
・まだ、作成中 | |
-------------------------------------------------------- | |
名前 | |
xmlCSV_Get_Main | |
XMLデータ(電文、ファイル)からXPATHで指定した内容をリスト表示する | |
書式 | |
xmlCSV_Get_Main(int opt, char *input_file, char *xpat[], char *nmsp[]) | |
[int opt] 0:メモリーから読込 1:ファイルから読込 2:標準入力から読込(パイプで入力) | |
[char *input_file] (opt=0):XML文字列(電文) (opt=1):XMLファイルのフルパス (opt=2):標準入力から取得 | |
[char *xpat[]] XML XPATHの配列※1 | |
[char *nmsp[]] MXL名前空間(ネームスペース)の配列※2 | |
※1)Ex | |
char *xpat[5]; | |
xstr_xpt[0]= "/x:Report/x:Control/x:Status"; | |
xstr_xpt[1]= "/x:Report/xh:Head/xh:TargetDateTime"; | |
xstr_xpt[2]= "/x:Report/xb:Body/xb:MeteorologicalInfos/xb:MeteorologicalInfo/xb:Item/xb:Station/xb:Name"; | |
xstr_xpt[3]= "/x:Report/xb:Body/xb:MeteorologicalInfos/xb:MeteorologicalInfo/xb:Item/xb:Station/xb:Location"; | |
xstr_xpt[4]= "/x:Report/xb:Body/xb:AdditionalInfo/xb:ObservationAddition/xb:Text"; | |
※2)Ex | |
char *nmsp[3]; | |
xstr_nsp[0]= "x,http://xml.kishou.go.jp/jmaxml1/"; | |
xstr_nsp[1]= "xh,http://xml.kishou.go.jp/jmaxml1/informationBasis1/"; | |
xstr_nsp[2]= "xb,http://xml.kishou.go.jp/jmaxml1/body/meteorology1/"; | |
説明 | |
【実行 (opt=0)】 | |
xmlCSV_Get_Main(0,<>.....</>(XML文字列),**xpat(配列データ),**nmsp(配列データ)); | |
【実行 (opt=1)】 | |
xmlCSV_Get_Main(1,/etc/zz/xxx.xml(XMLファイル格納場所),**xpat(配列データ),**nmsp(配列データ)); | |
【実行 (opt=2)】 | |
xmlCSV_Get_Main(0,<>.....</>(標準入力からのXML文字列),**xpat(配列データ),**nmsp(配列データ)); | |
(例:ドライバからの実行 cat tokusyu-3.xml|./xml_CSV 2) | |
【コンパイル方法】 | |
gcc -o xml_CSV xml_CSV_Get.c xml_CSV_Getlib.c -lxml2 | |
【デバグ用コンパイル(DEBUG1)】 | |
gcc -D DEBUG1 -o xml_CSV xml_CSV_Get.c xml_CSV_Getlib.c -lxml2 | |
【ファイル読込用の実行 (opt=1)】 | |
./xml_CSV 1 ./tokusyu-3.xml | |
【メモリー読込用の実行 (opt=0)】 | |
./xml_CSV 0 "`cat tokusyu-3.xml`" | |
【標準入力読込用の実行 (opt=2)】 | |
cat tokusyu-3.xml|./xml_CSV 2 | |
【コンパイル&実行】 | |
gcc -o xml_CSV xml_CSV_Get.c xml_CSV_Getlib.c -lxml2 && cat tokusyu-3.xml|./xml_CSV 2 | |
-------------------------------------------------------------------- | |
*/ | |
/* | |
---------------------------------------------------------------------- | |
xmlns属性(XML名前空間(ネームスペース))用 構造体 | |
---------------------------------------------------------------------- | |
"xml_CSV_Get.h" | |
---------------------------------------------------------------------- | |
XML Xpath取得用 構造体 | |
---------------------------------------------------------------------- | |
"xml_CSV_Get.h" | |
---------------------------------------------------------------------- | |
関数定義 | |
---------------------------------------------------------------------- | |
"xml_CSV_Get.h" | |
*/ | |
/* | |
-------------------------------------------------------------------------------------------------------- | |
メイン処理(配列で受け取ったデータをリスト構造体に格納する) | |
XMLパースに必要な情報「XMLデータの入力方式(opt)」、「XMLデータ」、「XML名前空間」、「Xpath」 | |
を引数として受け取りXpathで指定された部分をXMLデータから抽出する | |
【引数】 | |
int opt :XMLの入力を判別する(0:メモリーから読込 1:ファイルから読込 2:標準入力から読込(パイプで入力)) | |
char *input_file :XMLデータ文字列又は、XMLファイルへのパス | |
char *xpat[] :取得するXpathの配列データ | |
char *nmsp[] :XML名前空間配列データ | |
-------------------------------------------------------------------------------------------------------- | |
*/ | |
int xmlCSV_Get_Main(int opt, char *input_file, char *xpat[], char *nmsp[]){ | |
/* xmlns属性(XML名前空間(ネームスペース))に必要なデータをリスト構造に入れておく --------------------S | |
(データは何件あるかわからないのでリスト構造で動的に確保する) | |
*/ | |
ns_ptr = &st_dat; /* リスト構造スタート位置のアドレスを設定 */ | |
ns_ptr->next = NULL; /* リスト構造最初のnextにNULLを設定 */ | |
char *pref,*nsp,*cop; | |
const char *delim = ","; | |
/* 引数で受け取ったxmlns属性(XML名前空間(ネームスペース))配列の要素数取得 */ | |
int count; | |
for(count=0;nmsp[count]!=NULL;count++){} | |
count--; | |
int i; | |
for(i=0;i<count;i++){ | |
/* 構造体のメモリーを確保 */ | |
new_ptr = malloc(sizeof(struct XmlNs_Dat)); | |
if(new_ptr == NULL){ | |
printf("メモリを確保出来ない"); | |
exit(1); | |
} | |
/* 文字列分割(カンマ区切り) ----------S*/ | |
cop = malloc(strlen(nmsp[i])+1); | |
strcpy(cop,nmsp[i]); | |
pref = strtok(cop,delim); | |
nsp = strtok(NULL,delim); | |
#ifdef DEBUG1 | |
printf("文字列分割(カンマ区切り) ----------S\n"); | |
printf("DEBUG------strlen(xstr_nsp[i])+1 %d\n",strlen(nmsp[i])+1); | |
printf("DEBUG------cop %s\n",cop); | |
printf("DEBUG------pref %s\n",pref); | |
printf("DEBUG------nsp %s\n",nsp); | |
printf("文字列分割(カンマ区切り) ----------E\n"); | |
#endif | |
/* 文字列分割(カンマ区切り) ----------E*/ | |
new_ptr->prefixName = pref; /* プレフィックス名を格納 */ | |
new_ptr->nameSpace = nsp; /* ネームスペースを格納 */ | |
ns_ptr->next = new_ptr; /* 今データを入れた構造体を「next」(次の)ポインタに入れる */ | |
new_ptr->next = NULL; /* 次のためにnextクリアしておく */ | |
ns_ptr = new_ptr; /* */ | |
} | |
ns_ptr = st_dat.next; /* 開始位置を設定 */ | |
#ifdef DEBUG1 | |
/*** リストの表示 ***/ | |
printf("xmlns属性(XML名前空間(ネームスペース))リスト表示--------S\n"); | |
while (ns_ptr != NULL) { | |
printf("DEBUG------ns_ptr->prefixName=%s\n",ns_ptr->prefixName); | |
printf("DEBUG------ns_ptr->nameSpace=%s\n",ns_ptr->nameSpace); | |
ns_ptr = ns_ptr->next; | |
} | |
printf("xmlns属性(XML名前空間(ネームスペース))リスト表示--------E\n"); | |
#endif | |
/* xmlns属性(XML名前空間(ネームスペース))に必要なデータをリスト構造に入れておく --------------------E | |
*/ | |
/* XML Xpathに必要なデータをリスト構造に入れておく ----------------------------------------------S | |
(データは何件あるかわからないのでリスト構造で動的に確保する) | |
*/ | |
xpt_ptr = &xptSt_dat; /* リスト構造スタート位置のアドレスを設定 */ | |
xpt_ptr->next = NULL; /* リスト構造最初のnextにNULLを設定 */ | |
/* 引数で受け取ったXpath配列の要素数取得 */ | |
int count_xpt; | |
for(count_xpt=0;xpat[count_xpt]!=NULL;count_xpt++){} | |
count_xpt--; | |
int h; | |
for(h=0;h<count_xpt;h++){ | |
/* 構造体のメモリーを確保 */ | |
xptNew_ptr = malloc(sizeof(struct XmlXp_Dat)); | |
if(xptNew_ptr == NULL){ | |
printf("メモリを確保出来ない"); | |
exit(1); | |
} | |
xptNew_ptr->xpathName = xpat[h]; /* Xpathを格納 */ | |
xpt_ptr->next = xptNew_ptr; /* 今データを入れた構造体を「next」(次の)ポインタに入れる */ | |
xptNew_ptr->next = NULL; /* 次のためにnextクリアしておく */ | |
xpt_ptr = xptNew_ptr; /* */ | |
} | |
xpt_ptr = xptSt_dat.next; /* 開始位置を設定 */ | |
#ifdef DEBUG1 | |
/*** リストの表示 ***/ | |
printf("XML Xpathリスト表示--------------------S\n"); | |
while (xpt_ptr != NULL) { | |
printf("DEBUG------xpt_ptr->xpathName=%s\n",xpt_ptr->xpathName); | |
xpt_ptr = xpt_ptr->next; | |
} | |
printf("XML Xpathリスト表示--------------------E\n"); | |
#endif | |
/* XML Xpathに必要なデータをリスト構造に入れておく ----------------------------------------------E | |
*/ | |
/* */ | |
xml_CSV_Get_execute(opt, input_file); | |
return(0); | |
} | |
/* | |
-------------------------------------------------------------------------------------------------------- | |
メイン処理(リスト構造体に格納したデータからXpathを取得する) | |
-------------------------------------------------------------------------------------------------------- | |
*/ | |
int xml_CSV_Get_execute(int opt, char *input_file){ | |
xmlDocPtr doc; | |
xmlNodePtr root_element = NULL; | |
/* 標準入力からXMLデータを取得(パイプ)-----------------------------------S | |
*/ | |
char *buf; | |
char *buf2; | |
int r=2; | |
if(opt == 2){ | |
#ifdef DEBUG1 | |
printf("-ZZZZZZZ- %d\n",sizeof(stdin)); | |
#endif | |
buf = (char *)calloc(READ_SIZE,sizeof(char)); | |
buf2 = (char *)calloc(READ_SIZE,sizeof(char)); | |
while (fgets(buf,READ_SIZE,stdin) != NULL){ | |
#ifdef DEBUG1 | |
printf("-READ_SIZE buf--------- %d\n",sizeof(buf)); | |
printf("-READ_SIZE buf2--------- %d\n",sizeof(buf2)); | |
#endif | |
/* 容量が足りなくなったら再確保 */ | |
buf2 = (char *)realloc(buf2,READ_SIZE * r ); | |
#ifdef DEBUG1 | |
printf("--------- %s",buf); | |
#endif | |
/* 1行又は指定バイト(4096)単位で読み込んだデータを蓄積 */ | |
strcat(buf2,buf); | |
r++; | |
} | |
input_file = buf2; | |
#ifdef DEBUG1 | |
printf("-@@@@@@- %s",input_file); | |
printf("DEBUG------入力XMLデータ------\n %s\n",input_file); | |
#endif | |
} | |
/* 標準入力からXMLデータを取得(パイプ)-----------------------------------E | |
*/ | |
/* XMLメモリ読み込み-xmlReadMemory----------------------------------------S | |
【---メモ---】 | |
メモリ上のバッファからXMLを読込んで、xmlDoc構造体を生成する。 | |
XMLデータは改行されていても改行されていなくてもよい。 | |
【実行方法】 | |
./xml_CSV "`cat tokusyu-3.xml`" 又は cat tokusyu-3.xml|./xml_CSV | |
*/ | |
if(opt == 0 || opt == 2){ | |
int fsize = strlen(input_file); | |
#ifdef DEBUG1 | |
printf("DEBUG------XMLデータの文字数 %d\n",fsize); | |
#endif | |
doc = xmlReadMemory( input_file, fsize,NULL,"utf-8",0 ); | |
if (doc == NULL) { | |
fprintf(stderr, "Failed to parse %s\n", input_file); | |
return; | |
} | |
} | |
/* XMLファイル読み込み-xmlReadMemory----------------------------------------E | |
*/ | |
/* XMLファイル読み込み-xmlReadFile------------------------------------------S | |
【---メモ---】 | |
XMLファイルを引数に指定する場合 | |
*/ | |
if(opt == 1){ | |
doc = xmlReadFile(input_file, NULL, 0); | |
if (doc == NULL) { | |
fprintf(stderr, "Failed to parse %s\n", input_file); | |
return; | |
} | |
} | |
/* XMLファイル読み込み-xmlReadFile------------------------------------------E | |
*/ | |
/* | |
【---メモ---】 | |
xmlns属性(XML名前空間(ネームスペース))が設定されてしまっている場合 | |
「<Report xmlns="http://xml.kishou.go.jp/jmaxml1/" xmlns:jmx="http://xml.kishou.go.jp/jmaxml1/">」 | |
のような場合はネームスペースを登録する必要がある。 | |
↓ | |
xmlXPathRegisterNs(xpath_context, BAD_CAST "x",BAD_CAST "http://xml.kishou.go.jp/jmaxml1/"); | |
↓ | |
http://xml.kishou.go.jp/jmaxml1/ は 「x」に置き換える | |
*/ | |
/* getElementTagName-----------------------------------------S | |
*/ | |
ns_ptr = st_dat.next; /* ネームスペース用構造体の開始位置を設定 */ | |
xpt_ptr = xptSt_dat.next; /* Xpath用構造体の開始位置を設定 */ | |
/* 個別にXPATHを設定して取得 */ | |
execute_xpath_get(doc, "/descendant::*[name()='Title']",ns_ptr); | |
/* 個別にXPATHを設定して取得 */ | |
execute_xpath_get(doc, "/x:Report/x:Control/x:Status",ns_ptr); | |
/* リストに登録したもの全てを取得 */ | |
execute_xpath_ListGet(doc,xpt_ptr,ns_ptr); | |
/* getElementTagName-----------------------------------------E | |
*/ | |
/* 終了処理-----------------------------------------S | |
*/ | |
/* メモリ上のxmlDocを開放 */ | |
xmlFreeDoc(doc); | |
/* libxmlパーサを開放 */ | |
xmlCleanupParser(); | |
if(opt == 2){ | |
free(buf); | |
free(buf2); | |
} | |
/* 終了処理-----------------------------------------E | |
*/ | |
return 0; | |
} | |
/* | |
---------------------------------------------------------------------- | |
文字の置換 | |
---------------------------------------------------------------------- | |
*/ | |
void replace_char(char *str) | |
{ | |
/* | |
\n:FL:改行 | |
\r:CR:復帰 | |
\0:0x00:文字が空 | |
*/ | |
int i; | |
for (i = strlen(str) - 1; 0 <= i; i--) { | |
if ((str[i] == '\r') || | |
(str[i] == '\n') || | |
(str[i] == ' ')) { | |
/*空文字に置き換える*/ | |
str[i] = '\0'; | |
} | |
else { | |
break; | |
} | |
} | |
} | |
/* | |
---------------------------------------------------------------------- | |
---------------------------------------------------------------------- | |
*/ | |
void print_attr(xmlAttrPtr attr, FILE *output) | |
{ | |
xmlAttrPtr cur_attr = NULL; | |
for (cur_attr = attr; cur_attr; cur_attr = cur_attr->next) { | |
fprintf(output, "attr %s=%s\n", attr->name, attr->children->content); | |
} | |
} | |
/* | |
---------------------------------------------------------------------- | |
取得したXpathの情報表示 | |
---------------------------------------------------------------------- | |
*/ | |
void print_xpath_nodes(xmlNodeSetPtr nodes, FILE *output) | |
{ | |
xmlNodePtr cur; | |
int size; | |
int i; | |
char *content; | |
char buf[CONTENT_SIZE]; | |
size = (nodes) ? nodes->nodeNr : 0; | |
/* fprintf(output, "Result (%d nodes):\n", size);*/ | |
for(i = 0; i < size; ++i) { | |
if(nodes->nodeTab[i]->type == XML_NAMESPACE_DECL) { | |
xmlNsPtr ns; | |
ns = (xmlNsPtr)nodes->nodeTab[i]; | |
cur = (xmlNodePtr)ns->next; | |
#ifdef DEBUG1 | |
if(cur->ns) { | |
fprintf(output, | |
"= namespace \"%s\"=\"%s\" for node %s:%s", | |
ns->prefix, | |
ns->href, cur->ns->href, cur->name); | |
} | |
else { | |
fprintf(output, | |
"= namespace \"%s\"=\"%s\" for node %s", | |
ns->prefix, ns->href, cur->name); | |
} | |
#endif | |
} | |
else if(nodes->nodeTab[i]->type == XML_ELEMENT_NODE) { | |
cur = nodes->nodeTab[i]; | |
#ifdef DEBUG1 | |
if(cur->ns) { | |
fprintf(output, | |
"= element node \"%s:%s\"", | |
cur->ns->href, cur->name); | |
} | |
else { | |
fprintf(output, "= element node \"%s\"", | |
cur->name); | |
} | |
#endif | |
} | |
else { | |
cur = nodes->nodeTab[i]; | |
#ifdef DEBUG1 | |
fprintf(output, "= node \"%s\": type %d: ", cur->name, cur->type); | |
#endif | |
} | |
content = cur->children->content; | |
if (NULL != content) { | |
strcpy(buf, content); | |
replace_char(buf); | |
fprintf(output, " content :%s:%s\n", cur->name,buf); | |
} | |
else { | |
fprintf(output, " content (null)\n"); | |
} | |
print_attr(cur->properties, output); | |
} | |
} | |
/* | |
---------------------------------------------------------------------- | |
Xpath取得の実行(単体) | |
---------------------------------------------------------------------- | |
*/ | |
int execute_xpath_get(xmlDocPtr doc, xmlChar *xpath_expr ,struct XmlNs_Dat *lns) | |
{ | |
xmlXPathContextPtr xpath_context; | |
xmlXPathObjectPtr xpath_obj; | |
printf("---- XPath Get %s\n", xpath_expr); | |
/* xmlXPathNewContext */ | |
xpath_context = xmlXPathNewContext(doc); | |
if(xpath_context == NULL) { | |
fprintf(stderr,"Error: unable to create new XPath context\n"); | |
xmlFreeDoc(doc); | |
return -1; | |
} | |
/* | |
* 名前空間(ネームスペース)の設定 | |
*/ | |
/* | |
xmlXPathRegisterNs(xpath_context, BAD_CAST "x",BAD_CAST "http://xml.kishou.go.jp/jmaxml1/"); | |
xmlXPathRegisterNs(xpath_context, BAD_CAST "xh",BAD_CAST "http://xml.kishou.go.jp/jmaxml1/informationBasis1/"); | |
xmlXPathRegisterNs(xpath_context, BAD_CAST "xb",BAD_CAST "http://xml.kishou.go.jp/jmaxml1/body/meteorology1/"); | |
*/ | |
while (lns != NULL) { /* 次ポインタがNULLまで処理 */ | |
#ifdef DEBUG1 | |
printf("名前空間(ネームスペース)の設定----------------S\n"); | |
printf("DEBUG------lns->prefixName=%s\n",lns->prefixName); | |
printf("DEBUG------lns->nameSpace=%s\n",lns->nameSpace); | |
printf("名前空間(ネームスペース)の設定----------------E\n"); | |
#endif | |
/* lns->prefixName:プレフィックス名、lns->nameSpace:ネームスペースを登録 */ | |
xmlXPathRegisterNs(xpath_context, BAD_CAST lns->prefixName,BAD_CAST lns->nameSpace); | |
lns = lns->next; | |
} | |
/* xmlXPathEvalExpressionで取得 */ | |
xpath_obj = xmlXPathEvalExpression(xpath_expr, xpath_context); | |
if(xpath_obj == NULL) { | |
fprintf(stderr, | |
"Error: unable to evaluate xpath expression \"%s\"\n", | |
xpath_expr); | |
xmlXPathFreeContext(xpath_context); | |
xmlFreeDoc(doc); | |
return -1; | |
} | |
/* Print results */ | |
print_xpath_nodes(xpath_obj->nodesetval, stdout); | |
/* メモリ解放 */ | |
xmlXPathFreeObject(xpath_obj); | |
xmlXPathFreeContext(xpath_context); | |
} | |
/* | |
---------------------------------------------------------------------- | |
Xpath取得の実行(リストデータ内の全て) | |
---------------------------------------------------------------------- | |
*/ | |
int execute_xpath_ListGet(xmlDocPtr doc, struct XmlXp_Dat *xpt,struct XmlNs_Dat *lns) | |
{ | |
xmlXPathContextPtr xpath_context; | |
xmlXPathObjectPtr xpath_obj; | |
printf("---- XPath ListGet \n"); | |
/* xmlXPathNewContext */ | |
xpath_context = xmlXPathNewContext(doc); | |
if(xpath_context == NULL) { | |
fprintf(stderr,"Error: unable to create new XPath context\n"); | |
xmlFreeDoc(doc); | |
return -1; | |
} | |
/* | |
* 名前空間(ネームスペース)の設定-------------------------------------------- | |
*/ | |
while (lns != NULL) { /* 次ポインタがNULLまで処理 */ | |
#ifdef DEBUG1 | |
printf("名前空間(ネームスペース)の設定----------------S\n"); | |
printf("DEBUG------lns->prefixName=%s\n",lns->prefixName); | |
printf("DEBUG------lns->nameSpace=%s\n",lns->nameSpace); | |
printf("名前空間(ネームスペース)の設定----------------E\n"); | |
#endif | |
/* lns->prefixName:プレフィックス名、lns->nameSpace:ネームスペースを登録 */ | |
xmlXPathRegisterNs(xpath_context, BAD_CAST lns->prefixName,BAD_CAST lns->nameSpace); | |
lns = lns->next; | |
} | |
/* | |
* xmlXPathEvalExpressionで取得---------------------------------------------- | |
*/ | |
while (xpt != NULL) { /* 次ポインタがNULLまで処理 */ | |
xpath_obj = xmlXPathEvalExpression(xpt->xpathName, xpath_context); | |
if(xpath_obj == NULL) { | |
fprintf(stderr, | |
"Error: unable to evaluate xpath expression \"%s\"\n", | |
xpt->xpathName); | |
xmlXPathFreeContext(xpath_context); | |
xmlFreeDoc(doc); | |
return -1; | |
} | |
/* Print results */ | |
print_xpath_nodes(xpath_obj->nodesetval, stdout); | |
xpt = xpt->next; | |
} | |
/* メモリ解放 */ | |
xmlXPathFreeObject(xpath_obj); | |
xmlXPathFreeContext(xpath_context); | |
} | |
/* | |
---------------------------------------------------------------------- | |
DEBUG用関数 | |
---------------------------------------------------------------------- | |
*/ | |
int test(char *aa[]) | |
{ | |
/* 配列数確認 */ | |
int j=0; | |
for(j=0;NULL!=aa[j];j++){} | |
j--; | |
int i=0; | |
printf("TEST CODE DEBUG--------------配列数-----%d\n",j); | |
for(i=0; i < j ; i++){ | |
printf("TEST CODE DEBUG------%s\n",aa[i]); | |
} | |
} | |
/* | |
---------------------------------------------------------------------- | |
正規表現関数 | |
引数: | |
char *str :検索対象文字列 | |
char *regexstr :正規表現文字列 | |
戻り値: | |
int 0:マッチあり 1:マッチなし | |
REG_EXTENDED | |
regex に POSIX 拡張正規表現を使用する。もしこのフラグが設定されない場合、POSIX 標準正規表現が使われる。 | |
REG_ICASE | |
大文字小文字の違いを無視する。 | |
REG_NOSUB | |
このフラグを設定してコンパイルされたパターンバッファが regexec の引数に指定されると、パラメータ nmatch, pmatch が無視される。 | |
REG_NEWLINE | |
全ての文字にマッチするオペレータに改行をマッチさせない。 | |
---------------------------------------------------------------------- | |
*/ | |
int regex_seek(char *str, char *regexstr){ | |
regex_t regbuf; | |
size_t nmatch = 3; | |
regmatch_t pmatch[nmatch]; | |
int len=0; | |
char tmp[100]; | |
int ret=1; | |
memset(tmp, '\0', sizeof(tmp)); | |
/* 正規表現のコンパイルを行なう */ | |
if (regcomp(®buf, regexstr, REG_EXTENDED|REG_NEWLINE) != 0) { | |
printf("regex compile failed.\n"); | |
exit(1); | |
} | |
/* 正規表現による検索を実行する */ | |
if (regexec(®buf, str, nmatch, pmatch, 0) != 0) { | |
#ifdef DEBUG1 | |
printf("No match.\n"); | |
#endif | |
} | |
else { | |
#ifdef DEBUG1 | |
printf("nmatch!! \n"); | |
/* マッチした文字列は regmatch_t 構造体の配列にその位置が記録されている | |
rm_so:マッチした文字列の先頭へのインデックス | |
rm_eo:マッチした文字列の次の文字へのインデックス | |
*/ | |
len = pmatch[0].rm_eo - pmatch[0].rm_so; | |
printf("先頭:%d 次:%d LEN:%d\n",pmatch[0].rm_so,pmatch[0].rm_eo,len); | |
strncpy(tmp, &str[pmatch[0].rm_so], len); | |
printf("マッチ文字:%s\n",tmp); | |
#endif | |
ret=0; | |
} | |
/* 正規表現パターンバッファを解放 */ | |
regfree(®buf); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment