你想要的是一个“replaceDots”功能。
它的工作原理是记住最后一个有效项目的位置,然后如果你得到点然后删除该项目。完整的描述在这里“删除点段” https://www.rfc-editor.org/rfc/rfc3986。在 RFC 页面上搜索 Remove Dot Segments。
你需要不止一个循环。内部循环向前扫描并查看下一部分,然后如果它是点,则跳过当前部分等,但它可能比这更棘手。或者考虑将其分解为多个部分,然后遵循算法。
当输入缓冲区不为空时,循环如下:
A. 如果输入缓冲区以“../”或“./”前缀开头,则从输入缓冲区中删除该前缀;否则,
B. 如果输入缓冲区以前缀“/./”或“/.”开头,其中“.” 是一个完整的路径段,然后在输入缓冲区中将该前缀替换为“/”;否则,
C. 如果输入缓冲区以前缀“/../”或“/..”开头,其中“..”是完整的路径段,则在输入缓冲区中将该前缀替换为“/”并删除来自输出缓冲区的最后一段及其前面的“/”(如果有);否则,
D. 如果输入缓冲区只包含“.” 或“..”,然后将其从输入缓冲区中删除;否则,
E. 将输入缓冲区中的第一个路径段移动到输出缓冲区的末尾,包括初始“/”字符(如果有)和任何后续字符,直到但不包括下一个“/”字符或末尾的输入缓冲区。
最后,输出缓冲区作为 remove_dot_segments 的结果返回。功能。
它的工作原理是记住最后一个有效项目的位置,然后如果你得到点然后删除该项目。完整的描述在这里
这是我在 C++ 中的版本...
ortl_funcimp(len_t) _str_remove_dots(char_t* s, len_t len) {
len_t x,yy;
/*
Modifies the string in place by copying parts back. Not
sure if this is the best way to do it since it involves
many copies for deep relatives like ../../../../../myFile.cpp
For each ../ it does one copy back. If the loop was implemented
using writing into a buffer, you would have to do both, so this
seems to be the best technique.
*/
__checklenx(s,len);
x = 0;
while (x < len) {
if (s[x] == _c('.')) {
x++;
if (x < len) {
if (s[x] == _c('.')) {
x++;
if (x < len) {
if (s[x] == _c('/')) { // ../
mem_move(&s[x],&s[x-2],(len-x)*sizeof(char_t));
len -= 2;
x -= 2;
}
else x++;
}
else len -= 2;// .. only
}
else if (s[x] == _c('/')){ // ./
mem_move(&s[x],&s[x-1],(len-x)*sizeof(char_t));
len--;
x--;
}
}
else --len;// terminating '.', remove
}
else if (s[x] == _c('/')) {
x++;
if (x < len) {
if (s[x] == _c('.')) {
x++;
if (x < len) {
if (s[x] == _c('/')) { // /./
mem_move(&s[x],&s[x-2],(len-x)*sizeof(char_t));
len -= 2;
x -= 2;
}
else if (s[x] == _c('.')) { // /..
x++;
if (x < len) { //
if (s[x] == _c('/')) {// /../
yy = x;
x -= 3;
if (x > 0) x--;
while ((x > 0) && (s[x] != _c('/'))) x--;
mem_move(&s[yy],&s[x],(len-yy) * sizeof(char_t));
len -= (yy - x);
}
else {
x++;
}
}
else {// ends with /..
x -= 3;
if (x > 0) x--;
while (x > 0 && s[x] != _c('/')) x--;
s[x] = _c('/');
x++;
len = x;
}
}
else x++;
}
else len--;// ends with /.
}
else x++;
}
}
else x++;
}
return len;
}