正则表达式,检查最后一个组是否存在

时间:2013-05-30 09:39:37

标签: regex preg-match string-matching

我有这种网站的网址结构:

/some_url/{slug}/ 

其中{slug}包含有关字段排序(仅限价格和名称),订单方向(asc,desc),限制行(30,40或空)和演示文稿类型(列表或空)的信息。例如:

/some_url/price_desc_30_list/

正如您可以看到每个组以下划线分隔,但仅适用于中间组。每个组都是可选的,在前面的示例中,网址由三个组price_desc30list组成。我想要的是得到每个组的价值。

目前我的正则表达式是(?:(price|name)_(asc|desc))?(?:_?(30|40))?(?:_?(list))?,但是下划线存在问题(只有在以前的群组存在的情况下才需要在群组的初始化中使用它们)所以此网址/some_url/_30/和此/some_url/30/都将匹配,但我只需要/some_url/30/

1 个答案:

答案 0 :(得分:1)

好的,我尝试过这个:

\/([^_\/]+)(?:_([^_\/]+)?_?)?(?:_([^_\/]+)?_?)?(?:_([^_\/]+)?_?)?\/$

并在regex101上进行了测试。

不确定原因

\/([^_\/]+)(?:_([^_\/]+)?_?){0,3}\/$

虽然没有工作:(

编辑:新正则表达式

^\/(.*?)\/(?:(?<!\/_)(price|name)(?!_\/))?_?(?:(?<!\/_)(asc|desc)(?!_\/))?_?(?:(?<!\/_)(30|40)(?!_\/))?_?(?:(?<!\/_)(list)(?!_\/))?\/$

Tested

(?!...)是一个负前瞻,阻止了前瞻中字符集后跟的字符的匹配。例如。 (list)(?!_\/)阻止匹配list_/,因为list后跟_/

(?<!...)是一个负面的后瞻,并防止在lookbehind内的字符集前面加上一个字符的匹配。例如。 (?<!\/_)(list)阻止了/_list的匹配,因为list前面有/_