我需要解析很多文件名(我猜是多达250000),包括路径,并从中提取一些部分。
以下是一个例子:
原文:/my/complete/path/to/80/01/a9/1d.pdf
需要:8001a91d
我正在寻找的“模式”将始终以“/ 8”开头。我需要提取的部分形成一个8位十六进制数字的字符串。
我的想法如下(简化为演示):
/* original argument */
char *path = "/my/complete/path/to/80/01/a9/1d.pdf";
/* pointer to substring */
char *begin = NULL;
/* final char array to be build */
char *hex = (char*)malloc(9);
/* find "pattern" */
begin = strstr(path, "/8");
if(begin == NULL)
return 1;
/* jump to first needed character */
begin++;
/* copy the needed characters to target char array */
strncpy(hex, begin, 2);
strncpy(hex+2, begin+3, 2);
strncpy(hex+4, begin+6, 2);
strncpy(hex+6, begin+9, 2);
strncpy(hex+8, "\0", 1);
/* print final char array */
printf("%s\n", hex);
这很有效。我只是觉得这不是最聪明的方式。并且可能有一些陷阱我不认为自己。
那么,是否有人建议使用这种指针移位方式可能会有什么危险?你认为会有什么改进?
C是否提供了像s|/(8.)/(..)/(..)/(..)\.|\1\2\3\4|
这样的功能?如果我记得有些脚本语言有这样的功能;如果你知道我的意思。
答案 0 :(得分:2)
C本身并不提供此功能,但您可以使用POSIX正则表达式。它是一个功能齐全的正则表达式库。但对于像你这样简单的模式,这可能是最好的方式。
BTW,首选memcpy
到strncpy
。很少有人知道strncpy
有什么好处。而且我不是其中之一。
答案 1 :(得分:0)
在仅仅匹配/8./../../..
的简单情况下,我个人自己去寻找strstr()
解决方案(不需要外部依赖)。如果规则变得更多,你可以尝试词法分析器(flex和朋友),它们支持正则表达式。
在你的情况下是这样的:
h2 [0-9A-Fa-f]{2}
mymatch (/{h2}){4}
可行。您必须通过副作用将缓冲区设置为匹配,但词法分析器通常会返回标记标识符。
无论如何,你在没有依赖关系的情况下获得了正则表达式的强大功能,但却牺牲了生成的(读取:不可读)代码。
答案 2 :(得分:0)
/* original argument */
char *path = "/my/complete/path/to/80/01/a9/1d.pdf";
char *begin;
char hex[9];
size_t len;
/* find "pattern" */
begin = strstr(path, "/8");
if (!begin) return 1;
// sanity check
len = strlen(begin);
if (len < 12) return 2;
// more sanity
if (begin[3] != '/' || begin[6] != '/' || begin[9] != '/' ) return 3;
memcpy(hex, begin+1, 2);
memcpy(hex+2, begin+4, 2);
memcpy(hex+4, begin+7, 2);
memcpy(hex+6, begin+10, 2);
hex[8] = 0;
// For additional sanity, you could check for valid hex characters here
/* print final char array */
printf("%s\n", hex);