现在的位置: 首页 > 综合 > 正文

学用pcre

2013年08月11日 ⁄ 综合 ⁄ 共 3240字 ⁄ 字号 评论关闭

今天在vc下用pcre对cpp936里面的数据进行了提取,费了好长时间,知道了正则表达式的一些好处。原来我以为正则表达式都只用来识别的,但pcre中可以取出各个标记子表达式的位置,从而在exec时可以提取出需要的子串,非常好用。每个标记子表达式在posvec的序列中的位置是静态的。也就是你需要提取的子串的posvec你是知道的,其索引相当于从根节点先序遍历的索引(从0开始)。
不带括号的表达式部分可以认为是plain text,不是标记子表达式,posvec[2 * i]和pos[2 *i + 1]分别存放子串的起始终止位置,对于(...)*的序列是最后出现的那个子串的起始、终止位置,如果没有出现则是-1,-1,?、+应该类似的。注意在正则表达式常量中转移字符要加两个/。
自己写的这个程序到后来发现有很多冗余的地方,其中一个就是提取多个子串,只需要用一个正则表达式,因为每个标记子表达式的子串的索引是固定的。
正则表达式的好处应该是大量重复的文本处理,相对而言,也会比不用有趣一些。
程序没有什么教学价值,自己存起来而已。

#include <stdlib.h>
#include <stdio.h>
#include "pcre.h"
#include <windows.h>

long gethexval(long cnt, char* p)
{
long ret = 0;
for (long i = 0; i < cnt; ++i)
{
ret <<= 4;
if (p[i] <= '9')
{
ret += p[i] - '0';
}
else
{
ret += p[i] - 'A' + 10;
}
}
return ret;
}

int main()
{
int posvec[20];
char chs[1024];
const char* error;
int erroffset;
FILE* fp = fopen("c://cp936.txt", "rb");//original source:http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT

char* pattern_1 = "(0x[0-9A-F][0-9A-F]([0-9A-F][0-9A-F])?)(//t)(.)*";//提取gbkindex、同时给出剩余串位置的pattern
char* pattern_2 = "(0x[0-9A-F][0-9A-F][0-9A-F][0-9A-F])(//t)#(.)*";
pcre* regex_1 = pcre_compile(pattern_1, 0, &error, &erroffset, NULL);
int re;
long lastindex = 0;
char* pc;
long l;

if (regex_1 == NULL)
{
printf("PCRE compilation failed at offset %d : %s/n", erroffset, error);
fclose(fp);
return 1;
};
pcre* regex_2 = pcre_compile(pattern_2, 0, &error, &erroffset, NULL);
if (regex_2 == NULL)
{
printf("PCRE compilation failed at offset %d : %s/n", erroffset, error);
fclose(fp);
return 1;
}

for (; ;)
{
if (!fgets(chs, 1024, fp))
{
goto hell;
}

//先获得gbkindex
pc = chs;
re = pcre_exec(regex_1, NULL, pc, strlen(pc), 0, 0, posvec, 20);
if (re < 0)
{
goto l1;
}
printf("%.*s/n", posvec[3] - posvec[2], chs + posvec[2]);

//获得unicode代码
pc += posvec[7];
re = pcre_exec(regex_2, NULL, pc , strlen(pc), 0, 0, posvec, 20);
if (re < 0)
{
goto l1;
}
else
{
printf("%.*s/n", posvec[3] - posvec[2], pc + posvec[2]);
}

//获得comment
pc += posvec[5];
++pc;
l = strlen(pc);
pc[l - 1] = 0;
printf("%s/n", pc);
}

l1:
char* pattern_3 = "(0x[0-9A-F][0-9A-F])//t      //t#DBCS LEAD BYTE//r";//只需提取出unicode
pcre* regex_3 = pcre_compile(pattern_3, 0, &error, &erroffset, NULL);
if (regex_3 == NULL)
{
printf("PCRE compilation failed at offset %d : %s/n", erroffset, error);
fclose(fp);
return 1;
}

for (; ;)
{
pc = chs;
re = pcre_exec(regex_3, NULL, pc, strlen(pc), 0, 0, posvec, 20);
if (re < 0)
{
int dummy = 3;
goto l2;
}

printf("%.*s/n", posvec[3] - posvec[2], pc + posvec[2]);
if (!fgets(chs, 1024, fp))
{
goto hell;
}
}

l2:
char* pattern_4 = "(0x[0-9A-F][0-9A-F])//t      //t#UNDEFINED//r";
pcre* regex_4 = pcre_compile(pattern_4, 0, &error, &erroffset, 0);
if (regex_4 == NULL)
{
printf("PCRE compilation failed at offset %d : %s/n", erroffset, error);
fclose(fp);
return 1;
}
for (; ;)
{
pc = chs;
re = pcre_exec(regex_4, NULL, pc, strlen(pc), 0, 0, posvec, 20);
if (re < 0)
{
int dummy = 0;
goto l3;
}

printf("%.*s/n", posvec[3] - posvec[2], pc + posvec[2]);
if (!fgets(chs, 1024, fp))
{
goto hell;
}
}

l3:
char* pattern_5 = "(0x[0-9A-F][0-9A-F][0-9A-F][0-9A-F])//t(0x[0-9A-F][0-9A-F][0-9A-F][0-9A-F])//t(.)*";
pcre *regex_5 = pcre_compile(pattern_5, 0, &error, &erroffset, NULL);
if (regex_5 == NULL)
{
printf("PCRE compilation failed at offset %d : %s/n", erroffset, error);
fclose(fp);
return 1;
}
for (; ;)
{
pc = chs;
re = pcre_exec(regex_5, NULL, pc, strlen(pc), 0, 0, posvec, 20);
if (re < 0)
{
int dummy = 0;
goto l4;
}

printf("%.*s/n", posvec[3] - posvec[2], pc + posvec[2]);
printf("%.*s/n", posvec[5] - posvec[4], pc + posvec[4]);

if (!fgets(chs, 1024, fp))
{
goto hell;
}
}

l4:
for (; ;)
{
if (strlen(pc) && pc[0] > 27)
{
int dummy = 0;
goto l5;
}
if (!fgets(chs, 1024, fp))
{
goto hell;
}
}

l5:
hell:
fclose(fp);
return 0;
}

抱歉!评论已关闭.