如何使用正则表达式从URL中提取一个组以用于重定向?

时间:2016-11-11 01:13:50

标签: php regex

我已经阅读了Best RegEx Trick Ever并尝试在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可以很容易地为chicagoatlanta或任何其他没有空格或标点符号的城市名称。

我唯一能够弄清楚第一个字符串中只有newyork的隔离区如下:

/.*\.com\/(.[^\/]*)\/class-schedule/g

但是,这依赖于首先使用我无法使用的网址。

关于如何在不使用URL的情况下实现此目的的任何想法?

[编辑] 为了澄清我正在寻找的内容,我尝试从第一个字符串中获取结果并添加" location"对它,仍然使用正则表达式。所以:

http://www.test.com/newyork/class-schedule

会变成

http://www.test.com/location/newyork/class-schedule

使用

之类的东西

http://www.test.com/location/$1/class-schedule

2 个答案:

答案 0 :(得分:2)

试试这个:~/(\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]包含所有内容。

您可以在' MATCH INFORMATION'中看到捕获。在我的例子中regex101上的面板!

您发表评论后

[编辑2]

如果您要替换整个网址,则必须匹配整个网址,例如:.*?/(\w+)/[-a-z]+?/?(?:\?.*?)*(?:\s|$)将在此示例中执行。看到它在这里工作:https://regex101.com/r/4VMazZ/5

[编辑3] 添加最后一部分的捕获以供更换。

因此,当您想要重复使用最后一部分时,需要添加捕获括号:.*?/(\w+)/([-a-z]+?)/?(?:\?.*?)*(?:\s|$)

在此处查看:https://regex101.com/r/4VMazZ/6

答案 1 :(得分:1)

这可行吗?见here

(?<=location\/|\.\w{3}\/|\.\w{2}\/)(?!location).*?(?=\/|$)

它匹配.xxx/.xx/location/后的所有内容。我不知道是否存在一个字母域,在这种情况下,您可以在正则表达式开头的前瞻中添加|\.\w\/

  • (?<=location\/|\.\w{3}\/|\.\w{2}\/)是预测,因此只有在location/.xxx.xx
  • 之前才会匹配以下模式
  • .*?匹配每个角色(懒惰)
  • (?=\/|$)如果下一个字符为/或在结尾
  • ,则结束匹配

注意:如果location被视为网址的一部分,我不会认为您在正则表达式中提出的要求是正确的,因为城市名称可能位于任何位置串。如果是这样,那么你可以有一个城市列表,并检查网址的哪一部分匹配其中一个。

编辑:您需要多行m标记,以便$也匹配行尾