我们的 Web 应用程序允许用户指定他们自己的“slugs”,其中可以包含相对路径,例如 /somedir/some-file.htm。
在我们的路由配置中,我们需要确保只支持有效的 slug(带段)。
我使用的正则表达式是:
(^[a-z0-9])([a-z0-9-/]+)([a-z0-9])$
Run Code Online (Sandbox Code Playgroud)
这意味着:
不幸的是,这也意味着双斜线将匹配例如 somedir//subdir//some-file.htm 因为我的表达式允许一个或多个斜线。
如何更改它以允许段之间有零个或多个斜线。
我认为:
(^[a-z0-9])(/?[a-z0-9-]+/?)([a-z0-9])$
Run Code Online (Sandbox Code Playgroud)
会起作用,但不会。
^[a-z0-9]([a-z0-9-]*[a-z0-9])?(/[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$
编辑:如果你喜欢第一个正则表达式,请使用这个:
^(?!-)[a-z0-9-]+(?<!-)(/(?!-)[a-z0-9-]+(?<!-))*$
它看起来凌乱而复杂,但根据您的规范似乎是正确的。
[a-z0-9]([a-z0-9-]*[a-z0-9])?
匹配单个名称。/暂时忽略s。
然后它的其余部分是一个斜杠,然后是同样的东西。
正如 Karoly 的回答中提到的,这不包括文字句点,例如“some-file.htm”将与我写的正则表达式不匹配。
如果这是所需的行为,那么您实际上需要:
^[a-z0-9]([a-z0-9-\.]*[a-z0-9])?(/[a-z0-9]([a-z0-9-\.]*[a-z0-9])?)*$
最后,如果您只想在最后一部分中允许文字句点,那么您需要:
^[a-z0-9]([a-z0-9-]*[a-z0-9])?(/[a-z0-9]([a-z0-9-]*[a-z0-9])?)*(/[a-z0-9]([a-z0-9-\.]*[a-z0-9])?)?$
编辑:
一个想法是,这可以使用先行和后向来简化一些。
^[a-z0-9]([a-z0-9-]*[a-z0-9])?(/[a-z0-9]([a-z0-9-]*[a-z0-9])?)*(/[a-z0-9]([a-z0-9-\.]*[a-z0-9])?)?$
变成:
^(?!-)[a-z0-9-]+(?<!-)(/(?!-)[a-z0-9-]+(?<!-))*(/(?!-\.)[a-z0-9-\.]+(?<!-\.))?$