提取文件夹并保持正则表达组顺序不变

时间:2017-02-22 15:43:55

标签: regex

给出以下字符串:

/folder/subfolder/all
/folder/subfolder/all?a=b
/folder/anothersubfolder/all?a=b
/folder/all
/folder/all?a=b
/folder/anothersubfolder
/folder/anothersubfolder/all
/folder

子文件夹" all"是预定义的,需要从字符串中可能存在或不存在的任何其他子文件夹中单独提取。

这样的正则表达式
^\/(folder)(\/[^/?]*)?(\/[^/?]*)?(\?.*)?$

对我不起作用。应修复包含不同文件夹的组。有了这个正则表达式,子文件夹" all"是第2组或第3组。

正则表达式的结果应该是这样的:

  • 第1组:/文件夹(强制只能是" /文件夹")
  • 第2组:/子文件夹(可选,可以是除" / all&#34之外的任何字符串;)
  • 第3组:/ all(可选只能是" / all")
  • 第4组:?a = b(可选任何一组参数)

1 个答案:

答案 0 :(得分:1)

^\/(folder)((?:\/(?!all)[^/?]*)?)((?:\/all)?)((?:\?.*)?)$

[["folder", "/subfolder",        "/all", ""    ],
 ["folder", "/subfolder",        "/all", "?a=b"],
 ["folder", "/anothersubfolder", "/all", "?a=b"],
 ["folder", "",                  "/all", ""    ],
 ["folder", "",                  "/all", "?a=b"],
 ["folder", "/anothersubfolder", "",     ""    ],
 ["folder", "/anothersubfolder", "/all", ""    ],
 ["folder", "",                  "",     ""    ]]

这里有两个主要技巧:

  1. 非捕获组?:,它告诉正则表达式引擎不要保持匹配,但仍然使用它来将正则表达式部分聚集在一起。它允许我们执行((?:stuff)?)之类的操作,这会创建一个可以为空的强制组。

  2. 否定前瞻?!,告诉正则表达式与某个模式不匹配。所以在这种情况下(?!all)表示“all”不能在第二个目录块中。 (注意:这意味着第二个目录不能以“all”开头)