url中匹配特定请求参数的正则表达式

Regular expression to match the specific request parameters in a url

我有一个Url (https://example.com?&iframeLoad=true&firstName=&lastName=&email=&phone1=&address=&zipcode=07307&isAvailableReferral=true&isAvailableDirect=false)

我正在尝试替换名字、姓氏、电子邮件、phone、地址字段而不是其他字段。

这就是我目前使用正则表达式所做的事情 (&?(名字|姓氏|电子邮件|phone1|地址)=?[^&]*)

这基本上是 selects“&”后跟名字|姓氏|电子邮件|phone1|地址以及“=”之后的每个字符。请注意,如果“=”后跟“&”符号,则正则表达式不匹配。

我能够 select 每个字段都正确,但是当 URL 在“=”之后有一个“&”时,我的解决方案无法正常工作,因为它只是 select直到“&”字符的值。

因为有效的电子邮件可以包含“&”。我需要一个解决方案,其中正则表达式 selects 即使在“=”之后有“&”符号。

示例:&email=abc&xyz@.com - 在这种情况下,正则表达式仅 selects "&email=abc&" 而不是整个电子邮件。

根据 url 编码的规范,此任务可能无法明确完成。为了使这成为可能,数据集中的 the urls 必须标准化,这样每个参数后面都有一个等号,并且参数值中不能有其他杂散等号。如果这两个条件都为真,则以下将起作用:

正则表达式

&(firstName|lastName|email|phone1|address)=([^&]*(?:&[^&=]+(?=&|$))*)

另请注意,此正则表达式不涵盖其中一个所需参数是第一个参数的情况。因为 Javascript 正则表达式是有限的,而且无论如何这是一个特殊情况(以 ? 而不是 & 开头),这将需要以不同的方式处理,具体取决于你想做什么参数。匹配以下并替换为 ? 是一种删除参数的方法:

\?(firstName|lastName|email|phone1|address)=([^&]*(?:&[^&=]+(?=&|$))*)(?:&|$)

如果您不打算完全删除该参数,为简单起见,可以删除表达式末尾的 (?:&|$)

根据您打算用什么替换参数,您可能会发现调整表达式很有用,但这些表达式通常应该在上述规则内给出所需的输出。

工作原理

这里的技巧是有一个单独的非捕获组 (?:&[^&=]+(?=&|$))* 来处理参数字符串的其他部分,其中包含原始 & 符号但没有等号。字符 class [^&=]+ 确保子表达式没有 & 号或等号,先行 (?=&|$) 确保字符串后跟另一个参数或字符串结尾,而不是一个等号。整个组都有一个量词 *,因为它可以在初始参数后出现零次、一次或多次。

另请注意,为方便起见,参数名称和值的值存储在capturing groups 1 和2 中,以便于访问和解析。如果您不打算使用这些值,可以通过在 (.

之后添加 ?: 将它们替换为非捕获组

免责声明

如果任何参数缺少等号,则无法明确区分新 url 参数与先前 url 参数的值,因为在示例 https://example.com?&iframeLoad=true&email=abc&xyz@.com 中可以引用一个名为 email 且值为 abc&xyz@.com 的参数,或两个名为 emailxyz@.com 的参数(除非参数字符串列表和值列表字符串是标准化的,但这条路是疯狂的)。以类似的方式,随机等号欺骗解析器。正如@David Faber 提到的,通常 URL 中的 & 字符会被 URL 编码为 %26,以完全防止这种歧义。

您可能想考虑这样的事情:

[&?]((?:firstName|lastName|phone1|address|zipcode)=|email=(?:.*@.*\.)?)[^&]*

email 参数在这里作为特殊情况处理 - 我们检查本地部分后跟子域,同时允许没有&符号的 TLD(我相信这是安全的 - 我不'认为 TLD 可以包含这样的奇怪字符)。所有其他参数都正常处理。匹配项将作为名称=值对返回。 See Regex 101 here.