在 Positive Lookbehind 之后匹配所有特定字符

Matching all of a certain character after a Positive Lookbehind

我整个上午都在努力使正则表达式正确,但我碰壁了。在下面的字符串中,我不想匹配 .com/<first_word> 之后的每个正斜杠,除了任何 / after URL.

$string = "http://example.com/foo/12/jacket Input/Output";
    match------------------------^--^

斜杠之间的单词长度无关紧要。

正则表达式:(?<=.com\/\w)(\/) 结果:

$string = "http://example.com/foo/12/jacket Input/Output"; // no match
$string = "http://example.com/f/12/jacket Input/Output";   
    matches--------------------^

正则表达式:(?<=\/\w)(\/) 结果:

$string = "http://example.com/foo/20/jacket Input/O/utput"; // misses the /'s in the URL
    matches----------------------------------------^
$string = "http://example.com/f/2/jacket Input/O/utput"; // don't want the match between Input/Output
    matches--------------------^-^--------------^                    

因为 lookbehind 可以没有修饰符并且需要是零长度断言我想知道我是否刚刚走错了路并且应该寻找另一个正则表达式组合。

积极的回顾是正确的做法吗?或者除了大量的咖啡,我还缺少其他东西吗?

注意:标记为 PHP 因为正则表达式应该在 any[=36= 中工作] preg_* 个函数。

在这里使用 \K\G。抓住 groups

^.*?\.com\/\w+\K|\G(\/)\w+\K

查看演示。

https://regex101.com/r/aT3kG2/6

$re = "/^.*?\.com\/\w+\K|\G(\/)\w+\K/m"; 
$str = "http://example.com/foo/12/jacket Input/Output"; 

preg_match_all($re, $str, $matches);

Replace

$re = "/^.*?\.com\/\w+\K|\G(\/)\w+\K/m"; 
$str = "http://example.com/foo/12/jacket Input/Output"; 
$subst = "|"; 

$result = preg_replace($re, $subst, $str);

如果您想使用 preg_replace 那么这个正则表达式应该可以工作:

$re = '~(?:^.*?\.com/|(?<!^)\G)[^/\h]*\K/~';
$str = "http://example.com/foo/12/jacket Input/Output";
echo preg_replace($re, '|', $str);
//=> http://example.com/foo|12|jacket Input/Output

因此在开始 .com 后出现的第一个 / 之后用 | 替换每个 /

需要负面回顾 (?<!^) 以避免在没有开始 .com 的情况下替换字符串,例如 /foo/bar/baz/abcd.

RegEx Demo

另一个基于 \G and \K 的想法。

$re = '~(?:^\S+\.com/\w|\G(?!^))\w*+\K/~';
  • (:non capture group to set entry point ^\S+\.com/\w or glue matches\G(?!^)就可以了。
  • \w*+\K/ possessively matches any amount of word characters until a slash. \K resets 匹配。

See demo at regex101