如何使用字符串replace All regex仅在查询参数存在时替换该参数



我有以下URL:

https://test1.com/path?query1=value1
and
https://test2.com/path

我正在尝试向所有url添加额外的查询参数,所以我正在尝试类似的东西

url.replaceAll(/(.*)[?]?(.*)/g,"$1?newquery=newvalue&$2")

let url = "https://test1.com/path?query1=value1"
console.log(url.replaceAll(/^(.*)[?]?(.*)$/g,"$1?newquery=newvalue&$2"))
url = "https://test1.com/path"
console.log(url.replaceAll(/^(.*)[?]?(.*)$/g,"$1?newquery=newvalue&$2"))

但它并没有像预期的那样起作用,有人能透露一些的信息吗

首先让我们了解您的regex正在做什么,然后我们可以修复它。您的正则表达式:

^ - the beginning of the string
(.*) - match any character 0 or more times - as many times as possible (greedy)
[?]? - match `?` 0 or 1 times
(.*) - match any character 0 or more times - as many times as possible (greedy)
$ - the end of the string

实际上,这里的主要问题是第一个捕获组捕获尽可能多的次数,所以它总是匹配整个url。我们可以使用.*?使其不贪婪,因此我们最终使用^(.*?)[?]?(.*)$。然而,现在我们遇到的问题是,最后一个捕获组捕获了整个url——我们可以使其不贪婪,但它根本不匹配任何字符。相反,我们应该确保这个组只在?存在时进行捕获,这样我们就可以将[?]?设为非可选组,将其移动到下一个捕获组,并将最后一个组设为可选组,如下所示:([?](.*))?。当我们这样做的时候,我们不妨使用?而不是[?],最终得到^(.*?)(?(.*))?$。这是有效的,因为$表示我们想要捕捉到最后。有了这个,我们需要使用$3而不是$2,因为$2现在在替换时也包含?,所以我们可以使用非捕获组来消除这个问题。所以我们的最终正则表达式是/(.*?)(?:?(.*))?/g

您的最终代码将如下所示:

let url = "https://test1.com/path?query1=value1"
console.log(url.replaceAll(/^(.*?)(?:?(.*))?$/g,"$1?newquery=newvalue&$2"))
url = "https://test1.com/path"
console.log(url.replaceAll(/^(.*?)(?:?(.*))?$/g,"$1?newquery=newvalue&$2"))

最新更新