Question: I've read the [Best RegEx Trick Ever](http://www.rexegg.com/regex-best-trick.html) and tried to wrap my head around the other answers here on Stack Exchange and just can't seem to get it right. Take these three strings:

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

I need a regex that will extract the `newyork` from the first string and save it for a replace later, but will NOT match any part of the other strings. Also, for obscure reasons, I can not include `http://www.test.com` as a condition for matching (so I can't use anything before the slash that precedes `newyork`). Note that in this scenario, `newyork` could easily be `chicago`, `atlanta`, or any other city name with no spaces or punctuation.

The only thing I've been able to figure out that isolates only `newyork` in the first string is the following:

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

However, this relies on using the URL first which I can't use.

Any ideas on how to achieve this WITHOUT using the URL?

[EDIT]
To clarify what I'm looking for, I'm trying to take the results from the first string and add "location" to it, still using regex. So:

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

would become 

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

using something like 

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

Answer: 
Try this: `~/(\w+)/[-a-z]+?/?(?:\?.*?)*(:?\s|$)~gm`

See it working here: <https://regex101.com/r/4VMazZ/3>.

So it will use the end of URL instead of the beginning and match only the word between slash 2 and 3 from the end. There can be a query string it will still work.

---

**[EDIT 1]**

I exchanged 2 chars doing typo in the end so it was capturing one extra group: `/(\w+)/[-a-z]+?/?(?:\?.*?)*(?:\s|$)`. here: <https://regex101.com/r/4VMazZ/4>

If you use `preg_match($pattern, $string, $matches);` the result you want (newyork) will be in `$matches[1];`, `$matches[0]` contains everything.

You can see the captures in 'MATCH INFORMATION' panel on regex101 in my example!

---

**[EDIT 2]** after your comment.

If you want to replace the whole url you have to match the whole URL, something like this: `.*?/(\w+)/[-a-z]+?/?(?:\?.*?)*(?:\s|$)` will do in this example. See it working here: <https://regex101.com/r/4VMazZ/5>

---

**[EDIT 3]** Add capturing of last part for replacement.

So as you want to reuse last part you need to add capturing parenthesis: `.*?/(\w+)/([-a-z]+?)/?(?:\?.*?)*(?:\s|$)`.

See it working here: <https://regex101.com/r/4VMazZ/6>
Could this work? See it [here](https://regex101.com/r/st83Ya/2).

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

```

It matches everything following `.xxx/` or `.xx/` or `location/`. I don't know if one letter domain exist, in this case, you can add `|\.\w\/` to the lookahead at the start of the regex.

* `(?<=location\/|\.\w{3}\/|\.\w{2}\/)` is a lookahead, so it matches the following pattern only if preceded by `location/` or `.xxx` or `.xx`
* `.*?` matches every character (lazy)
* `(?=\/|$)` end match if next character is `/` or on line end

**Note:** If `location` is counted as part of the url, I don't think what you are asking is possible in regex, as the city name could be anywhere in string. If so, then you could have a list of cities and check what part of the url matches one of them.

EDIT: You need the multiline `m` flag so `$` also matches end of line