我已经阅读了最好的RegEx技巧,并试图在Stack Exchange上找到其他答案,但似乎就是找不到正确的答案。取这三个字符串:
http://www.test.com/newyork/class-schedule
http://www.test.com/location/newyork/class-schedule
http://www.test.com/location/newyork/training
我需要一个正则表达式,它将从第一个字符串中提取newyork
并保存它以供以后替换,但不会匹配其他字符串的任何部分。此外,由于一些模糊的原因,我不能将http://www.test.com
作为匹配的条件(所以我不能在newyork
之前的斜杠之前使用任何内容)。注意,在这个场景中,newyork
可以很容易地是chicago
、atlanta
或任何其他没有空格或标点符号的城市名称。
我唯一能弄清楚的是,在第一个字符串中只隔离newyork
如下:
/.*'.com'/(.[^'/]*)'/class-schedule/g
但是,这依赖于首先使用URL,而我不能使用。
关于如何在不使用URL的情况下实现这一点的任何想法?
[编辑]为了澄清我在寻找什么,我试图从第一个字符串中获取结果,并向其添加"位置",仍然使用regex。所以:
http://www.test.com/newyork/class-schedule
变成
http://www.test.com/location/newyork/class-schedule
使用类似
的内容 http://www.test.com/location/$1/class-schedule
试试:~/('w+)/[-a-z]+?/?(?:'?.*?)*(:?'s|$)~gm
看它在这里工作:https://regex101.com/r/4VMazZ/3.
所以它将使用URL的结尾而不是开头,并且只匹配末尾的斜杠2和3之间的单词。可以有一个查询字符串,它仍然可以工作。
[编辑1]
我交换了2个字符,最后做错字,所以它捕获了一个额外的组:/('w+)/[-a-z]+?/?(?:'?.*?)*(?:'s|$)
。这里:https://regex101.com/r/4VMazZ/4
如果您使用preg_match($pattern, $string, $matches);
,您想要的结果(newyork)将在$matches[1];
中,$matches[0]
包含所有内容。
在我的示例中,您可以在regex101的'MATCH INFORMATION'面板中看到捕获!
[EDIT 2]在你的评论后面。
如果你想替换整个url,你必须匹配整个url,像这样:.*?/('w+)/[-a-z]+?/?(?:'?.*?)*(?:'s|$)
将在这个例子中完成。查看它的工作情况:https://regex101.com/r/4VMazZ/5
[EDIT 3]添加最后一个部件的捕获用于替换。
所以当你想重用最后一部分时,你需要添加捕获括号:.*?/('w+)/([-a-z]+?)/?(?:'?.*?)*(?:'s|$)
.
看它在这里工作:https://regex101.com/r/4VMazZ/6
这可行吗?看这里
(?<=location'/|'.'w{3}'/|'.'w{2}'/)(?!location).*?(?='/|$)
它匹配.xxx/
或.xx/
或location/
之后的所有内容。我不知道是否存在一个字母域,在这种情况下,您可以将|'.'w'/
添加到regex开头的前瞻性。
-
(?<=location'/|'.'w{3}'/|'.'w{2}'/)
是前瞻性的,因此只有在location/
或.xxx
或.xx
之前才匹配以下模式 -
.*?
匹配每个字符(惰性) -
(?='/|$)
结束匹配如果下一个字符是/
或在行结束
注意:如果location
被算作url的一部分,我不认为你所问的是可能的regex,因为城市名称可以在字符串的任何地方。如果是这样,那么你可以有一个城市列表,并检查url的哪个部分与其中一个匹配。
m
标志,所以$
也匹配行结束