消除仅有的双斜杠和额外的斜杠,并替换为一个斜杠

4
我遇到了一个问题。我想用一个斜杠替换URL中的双斜杠或多余斜杠,但是我做错了。要求斜杠应位于URL的中间或结尾,不应与协议双斜杠匹配,例如http://https://。但是我的正则表达式也匹配了这些斜杠。如何忽略协议斜杠?

const example1 = `https://example.com/home2`;
const example2 = `http://example.com/home2/`;
const example3 = `http://example.com//home2///`;
const example4 = `http://example.com/////home2///`;
const example5 = `http://example.com/////home2///heloo//////`;
const example6 = `http://example.com////home2/////////////`;
const example7 = `https://example.com////home2/////////////`;
const example8 = `http://localhost:9000/////`;

const patt = /\/\/+/g;

const res1 = patt.test(example1) ? example1.replace(patt, '/') : example1;
const res2 = patt.test(example2) ? example2.replace(patt, '/') : example2;
const res3 = patt.test(example3) ? example3.replace(patt, '/') : example3;
const res4 = patt.test(example4) ? example4.replace(patt, '/') : example4;
const res5 = patt.test(example5) ? example5.replace(patt, '/') : example5;
const res6 = patt.test(example6) ? example6.replace(patt, '/') : example6;
const res7 = patt.test(example7) ? example7.replace(patt, '/') : example7;
const res8 = patt.test(example8) ? example8.replace(patt, '/') : example8;

// The results should be something like this.
console.log(res1); // https://example.com/home2 => https://example.com/home2
console.log(res2); // http://example.com/home2/ => http://example.com/home2/
console.log(res3); // http://example.com//home2/// => http://example.com/home2/
console.log(res4); // http://example.com/////home2/// => http://example.com/home2/
console.log(res5); // http://example.com/////home2///heloo////// => http://example.com/home2/heloo/
console.log(res6); // http://example.com////home2///////////// => http://example.com/home2/
console.log(res7); // https://example.com////home2///////////// => https://example.com/home2/
console.log(res8); // http://localhost:9000///// => http://localhost:9000/

2个回答

2
一种负向回顾表达式会起作用:(?<!:)\/\/+ 回顾表达式允许您检查匹配其余部分之前的字符,而实际上不包括它们在匹配中。负向回顾测试这些前导字符不匹配。在这种情况下,(?<!:) 是负向回顾,确保在表达式的其余部分之前没有冒号,但不会将该前导字符包括在最终匹配中。

太好了!最后一件事?<!,这些符号在捕获组中的意义是什么? - John Doe
这就是它成为负向后瞻的原因。使用'?'开始一个捕获组,使其成为前瞻/后瞻。'<'指定了一个后瞻。'!'表示否定。 - Ouroborus

1
您可以将函数传递给字符串替换。您可以通过省略第一次出现来进行替换。
let str = 'http://example.com//home1///';

str = str.replace(/\/\/+/g, (i => m => !i++ ? m : '/')(0));
console.log(str);

谢谢您的回答。我们是否可以使用正则表达式忽略第一次出现? - John Doe
似乎仅通过正则表达式无法实现。 - shehanpathi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接