ここで必要なのは「replaceDots」関数です。
これは、最後の有効なアイテムの位置を記憶し、ドットが表示された場合はそのアイテムを削除することで機能します。完全な説明はここにあります「ドットセグメントの削除」https://www.rfc-editor.org/rfc/rfc3986。RFCページでドットセグメントの削除を検索します。
複数のループが必要です。内側のループは前方をスキャンして次の部分を調べ、ドットの場合は現在の部分がスキップされるなどですが、それよりも難しい場合があります。または、それをいくつかの部分に分割してから、アルゴリズムに従うことを検討してください。
入力バッファが空でない間、次のようにループします。
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;
}