如何强制正则表达式捕获最大的匹配项?
How to Force Regex to Capture Largest Match?
我正在尝试防止对网站的恶意注入。我这样做的方法是创建一个函数,该函数 "trims" URL 的任何额外部分都会使其成为非法。
为了使 URL 合法,它必须遵循以下格式:
(anything)(one of several specificied path predecessors)(specific page)
例如,假设您的路径前辈是...
["services", "services/city", "specials", "specials/limited/"]
一些示例输入和结果:
www.fake.com/services/home -> (legal, no trim) ->
www.fake.com/services/home
www.fake.com/services/city/nyc -> (legal, no trim) ->
www.fake.com/services/city/nyc
www.fake.com/services/city/nyc/fakeinjection.txt -> (illegal) ->
www.fake.com/services/city/nyc
www.fake.com/specials/limited/california/fake/fake/fake.bak ->
(illegal) -> www.fake.com/specials/limited/california
所以我写了下面的正则表达式只匹配输入的合法部分URL:
/.*(services|services\/city|specials|specials\/limited)\/[^\/]*/gi
问题在于它并不总是捕获最大可能的匹配项,因此无意中trim忽略了太多。例如:
www.fake.com/services/city/nyc -> (应该合法,不应该trim) ->
www.fake.com/services/city/
我想我明白为什么会这样。我相信它正在捕获它看到的第一件事并与之匹配。但是我需要强制它尽可能地取最大的一个,必要时只 trimming。我认为 "greedy" 标志可以帮助做到这一点,但事实并非如此。
任何人都可以提供一些解决方案的指导吗?将不胜感激。
(PS。以防万一,我使用的语言是 javascript)
如果你有一个未锚定的交替组,你应该把最长的交替组放在第一位。在任何 NFA 正则表达式中,第一个匹配的分支停止处理交替组并继续处理后续模式。
所以,您可以使用
/.*(services\/city|specials\/limited|services|specials)\/[^\/]*/
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^
如果您使用可选组手动创建模式以减少回溯,您可以进一步增强此列表:
/.*(services(?:\/city)?|specials(?:\/limited))\/[^\/]*/
甚至
/.*(s(?:ervices(?:\/city)?|pecials(?:\/limited)))\/[^\/]*/
我正在尝试防止对网站的恶意注入。我这样做的方法是创建一个函数,该函数 "trims" URL 的任何额外部分都会使其成为非法。
为了使 URL 合法,它必须遵循以下格式:
(anything)(one of several specificied path predecessors)(specific page)
例如,假设您的路径前辈是...
["services", "services/city", "specials", "specials/limited/"]
一些示例输入和结果:
www.fake.com/services/home -> (legal, no trim) -> www.fake.com/services/home
www.fake.com/services/city/nyc -> (legal, no trim) -> www.fake.com/services/city/nyc
www.fake.com/services/city/nyc/fakeinjection.txt -> (illegal) -> www.fake.com/services/city/nyc
www.fake.com/specials/limited/california/fake/fake/fake.bak -> (illegal) -> www.fake.com/specials/limited/california
所以我写了下面的正则表达式只匹配输入的合法部分URL:
/.*(services|services\/city|specials|specials\/limited)\/[^\/]*/gi
问题在于它并不总是捕获最大可能的匹配项,因此无意中trim忽略了太多。例如:
www.fake.com/services/city/nyc -> (应该合法,不应该trim) -> www.fake.com/services/city/
我想我明白为什么会这样。我相信它正在捕获它看到的第一件事并与之匹配。但是我需要强制它尽可能地取最大的一个,必要时只 trimming。我认为 "greedy" 标志可以帮助做到这一点,但事实并非如此。
任何人都可以提供一些解决方案的指导吗?将不胜感激。
(PS。以防万一,我使用的语言是 javascript)
如果你有一个未锚定的交替组,你应该把最长的交替组放在第一位。在任何 NFA 正则表达式中,第一个匹配的分支停止处理交替组并继续处理后续模式。
所以,您可以使用
/.*(services\/city|specials\/limited|services|specials)\/[^\/]*/
^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^ ^^^^^^^^
如果您使用可选组手动创建模式以减少回溯,您可以进一步增强此列表:
/.*(services(?:\/city)?|specials(?:\/limited))\/[^\/]*/
甚至
/.*(s(?:ervices(?:\/city)?|pecials(?:\/limited)))\/[^\/]*/