使用正则表达式 accur 'undefined'拆分字符串



我希望从URL中提取以下字段,如协议,域名,端口和路径。

我知道这个split功能对我很有帮助。这是我的代码

"https://www.test.com:8081/a/b/c".split(/(://)|(:)|(/)/)

结果是

["https", "://", undefined, undefined, "www.test.com", undefined, ":", undefined, "8081", undefined, undefined, "/", "a", undefined, undefined, "/", "b", undefined, undefined, "/", "c"]

我希望结果是

['https', '://', 'www.test.com', ':', '8081', '/', 'a/b/c']

为什么会发生undefined?如何纠正我的正则表达式?

当然,捕获组会包含在split的结果中 - 当您与在特定迭代中不匹配的捕获组交替时,该捕获组将不会匹配,但它仍然是split内的捕获组,因此undefined被添加到该位置的数组中。例如:

console.log('abc'.split(/b|(wontmatch)/));
// a more complicated example:
console.log('abcde'.split(/(b)|(d)/));
/*
[
"a",        split substring
"b",        b was captured, so it's included in the match
undefined,  the (d) part did not match, but it's another capturing group, so "undefined"
"c",        split substring
undefined,  the (b) part did not match, but it's another capturing group, so "undefined"
"d",        d was captured, so it's included in the match
"e"         split substring
]
*/

您正在经历的行为只是上述更复杂的版本。

您可以考虑使用match而不是split,它可能更容易理解:

const str = "https://www.test.com:8081/a/b/c";
const matches = str.match(/([^:]+)(://)([^:]+)(:)(d+)(/)(.*$)/);
console.log(matches);
// I expect the result is
// ['https', '://', 'www.test.com', ':', '8081', '/', 'a/b/c']

或者,如果您只需要协议、域名、端口和路径,请删除无用的捕获组:

const str = "https://www.test.com:8081/a/b/c";
const [, protocol, domain, port, path] = str.match(
/([^:]+)://([^:]+):(d+)/(.*$)/
);
console.log(protocol, domain, port, path);

如果端口是可选的,则将其和前面的:放入可选的非捕获组中,并将第二个字符集更改为[^:/]以确保它与斜杠不匹配:

const str = "https://www.test.com/a/b/c";
const [, protocol, domain, port, path] = str.match(
/([^:]+)://([^:/]+)(?::(d+))?/(.*$)/
);
console.log(protocol, domain, port, path);

当您将捕获组放入正则表达式中时,结果将包括与每个组匹配的任何条目。由于您的组位于不同的备选项中,因此当一个备选项匹配时,将不会使用其他备选项,因此结果中的相应元素将undefined

与其在每个备选方案中放置一个组,不如将组包裹在所有这些选项周围。

console.log("https://www.test.com:8081/a/b/c".split(/(://|:|/)/));

还有另一种方法可以使用URL对象提取参数

var url = new URL('https://www.test.com:8081/a/b/c');
console.log(url.protocol);
console.log(url.hostname);
console.log(url.port);
console.log(url.pathname);

相关内容

最新更新