1

我需要解析很多文件名(我猜最多 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|?如果我没记错的话,一些脚本语言有这样的特性;如果你明白我的意思。

4

3 回答 3

2

C 本身不提供此功能,但您可以使用 POSIX 正则表达式。它是一个功能齐全的正则表达式库。但是对于像你这样简单的模式,这可能是最好的方法。

顺便说一句,更memcpy喜欢strncpy. 很少有人知道什么strncpy是好的。而我不是其中之一。

于 2013-03-03T09:33:49.677 回答
0

在仅匹配的简单情况下,/8./../../..我自己会亲自寻求strstr()解决方案(不需要外部依赖)。如果规则变得更多,您可以尝试词法分析器(flex和朋友),它们支持正则表达式。

在你的情况下是这样的:

h2           [0-9A-Fa-f]{2}
mymatch      (/{h2}){4}

可以工作。尽管词法分析器通常返回令牌标识符,但您必须通过副作用将缓冲区设置为匹配。

无论如何,您将在没有依赖关系的情况下获得正则表达式的强大功能,但会以生成(读取:不可读)代码为代价。

于 2013-03-03T10:24:14.073 回答
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);
于 2013-03-03T11:57:50.197 回答