我已经研究了一段时间,并且没有找到匹配以下模式的线索(虽然我也是正则表达式的新手),它看起来像
/abc/foo/bar(/*)
或
/abc/foo/bar/stop
所以我想匹配并捕获上面的字符串为/ abc / foo / bar。现在" /停止"是一个可选的字符串,可以附加在模式的末尾。目标是获得所需的捕获,同时忽略"停止"如果它们出现(如果"停止"多次停留在第一个"停止"),同时允许尽可能多的斜线在中间除了线末端的斜线。
如果我只是这样做:
^(/.*[^/])/*$
在我删除可能的最后一次出现之前,包含所有斜杠是贪婪的;但是为了接受我有一个可选的" / stop"的第二种情况,我需要以非贪婪的方式进行匹配,直到找到第一种可能的" / stop"并停在那里。
我如何制作一个匹配两种情况的正则表达式?
编辑:不确定我之前的例子是否不够清楚。尝试提供更多,说我想匹配并捕获" / abc / foo / bar"在以下所有字符串中:
/abc/foo/bar
/abc/foo/bar/
/abc/foo/bar///
/abc/foo/bar/stop
/abc/foo/bar/stop/foo/bar/stop/stop
/abc/foo/bar//stop
虽然它不符合以下任何一项:
/abc/foo/bar/sto (will match the whole "/abc/foo/bar/sto" instead)
/abc/foo/bar/abc/foo/bar (it will catch "/abc/foo/bar/abc/foo/bar" instead)
让我知道这是否足够清楚。谢谢!
答案 0 :(得分:3)
试试这个:
/^(?:\/+(?!$|(?:stop\/?))[^\/]+)*/
说明:
这匹配字符串的开头(^
),后跟以下模式的零个或多个实例:
\/+
)未跟随字符串末尾($
)或stop
,后跟[^\/]+
)
这是一个Debuggex Demo工作单元测试。
编辑:这是一个替代方案,可以说更简单,正则表达式:
/^.+?(?=\/*$|\/+stop\b)/
这会以非贪婪的方式匹配一个或多个字符,然后在匹配后的任何内容为以下之一时停止:
$
),可能前面有一个或多个斜杠(\/*
)此处有Regex101 demo此选项。
编辑2:如果您想对此进行测试,这是一个简单的JavaScript测试,它针对各种测试字符串测试上面的第二个正则表达式,并将结果记录到控制台:
var re = /^.+?(?=\/*$|\/+stop\b)/,
test_strings = ["/abc/foo/bar",
"/abc/foo/bar/",
"/abc/foo/bar///",
"/abc/foo/bar/stop",
"/abc/foo/bar/stop/foo/bar/stop/stop",
"/abc/foo/bar//stop",
"/abc/foo/bar/sto",
"/abc/foo/bar/abc/foo/bar"];
for(var s = 0; s < test_strings.length; s++) {
console.log(test_strings[s].match(re)[0]);
}
/*
Results:
/abc/foo/bar
/abc/foo/bar
/abc/foo/bar
/abc/foo/bar
/abc/foo/bar
/abc/foo/bar
/abc/foo/bar/sto
/abc/foo/bar/abc/foo/bar
*/
答案 1 :(得分:2)
您可以尝试这样的事情:
^((?:/[^/]+)+?)(?:/+|/+stop(?:/.*)?)$
如果原子组可用,最好写一下:
^((?:/[^/]+)+?)(?>/+$|/+stop(?:/.*)?)
如果可以预见:
^/(?>[^/]+|/(?!/*(?:$|stop(?:/|$))))+
ps:如果您的分隔符是斜杠,请不要忘记逃避斜杠。
正如Ed Cottrell所注意到的那样,原子分组等功能在Javascript等语言或Python的re模块中不可用。但是,使用前瞻是自然原子这一事实可以有效地模拟该特征:(?>a+)
&lt; =&gt; (?=(a+))\1