相对路径正则表达式

Ben*_*ter 4 regex

我们的 Web 应用程序允许用户指定他们自己的“slugs”,其中可以包含相对路径,例如 /somedir/some-file.htm。

在我们的路由配置中,我们需要确保只支持有效的 slug(带段)。

我使用的正则表达式是:

(^[a-z0-9])([a-z0-9-/]+)([a-z0-9])$
Run Code Online (Sandbox Code Playgroud)

这意味着:

  • 有效的 slug 将匹配例如 some-file.htm
  • 带有段(相对路径)的有效 slug 将匹配例如 somedir/subdir/some-file.htm
  • 绝对 URL 将不匹配,例如 /somedir/some-file.htm
  • 尾随 / 或 - 将不匹配,例如 -slug-

不幸的是,这也意味着双斜线将匹配例如 somedir//subdir//some-file.htm 因为我的表达式允许一个或多个斜线。

如何更改它以允许段之间有零个或多个斜线。

我认为:

(^[a-z0-9])(/?[a-z0-9-]+/?)([a-z0-9])$
Run Code Online (Sandbox Code Playgroud)

会起作用,但不会。

Omn*_*ity 5

^[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-\.]+(?<!-\.))?$