188

I'm trying to catch the last part after the last backslash
I need the \Web_ERP_Assistant (with the \)

My idea was :

C:\Projects\Ensure_Solution\Assistance\App_WebReferences\Web_ERP_WebService\Web_ERP_Assistant


\\.+?(?!\\)      //  I know there is something with negative look -ahead `(?!\\)`

But I can't find it.

[Regexer Demo]

shA.t
  • 16,580
  • 5
  • 54
  • 111
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • 4
    I appreciate that your question pertained to regexes, but are you sure this is the best tool to use here? Most standard libraries will have a method that will retrieve the last path name in a given directory. This also takes into account what the directory separator is on a given OS. – Steve Rukuts Dec 04 '11 at 10:43
  • @Raskolnikov I need that in regex. I know the Pth.getFileNameWithoutExtension. The QUestion is tagged as regex – Royi Namir Dec 04 '11 at 10:44
  • 2
    OK, fair enough, just making sure. I'll leave it to people more skilled in regexes then. – Steve Rukuts Dec 04 '11 at 10:44

7 Answers7

143

Your negative lookahead solution would e.g. be this:

\\(?:.(?!\\))+$

See it here on Regexr

stema
  • 90,351
  • 20
  • 107
  • 135
  • 4
    The `(?:` is the start of a non capturing group. The `.` is any character, this checks any character if it is not followed by a `\`. – stema Dec 04 '11 at 12:18
  • The Multi line is only for the Regexr test needed. It changes the meaning of the the `$`. Standard is end of the string, with Multiline its end of the row. Because the test text in Regexr has multiple rows I need this option there. – stema Dec 04 '11 at 12:20
  • 1
    what if i want the same reqeust as my original question , but without the \ in the beginning ? – Royi Namir Jul 07 '12 at 12:09
  • Just remove the `\\` from the regex? – stema Jul 09 '12 at 06:09
  • 4
    `(?:[^\\/](?!(\\|/)))+$` removes the slash at the beginning and copes with both forward and back slashes. It also matches the entire string for pathes without any slashes in them e.g. _manual.doc_ – mrswadge Sep 10 '13 at 12:01
  • 5
    In a Tempered Greedy Token, the dot should always come after the lookahead: `(?:(?!\\).)+`. ([ref](http://stackoverflow.com/questions/30900794/tempered-greedy-token-what-is-different-about-placing-the-dot-before-the-negat)) Also, your example on RegExr uses two backslashes to separate path components; there should be only one, and the regex should *match* only one. ([demo](http://regexr.com/3dpga)) – Alan Moore Jul 09 '16 at 04:11
  • This seems to fail if there is a `.` in the file path – ScottishTapWater Mar 02 '17 at 15:56
  • For extracting the extension of a file one could use [`.*\.(?!\.)(.*)`](https://regex101.com/r/IDgurh/1). – Nae Jun 08 '18 at 07:06
  • This does the job even for a forward slash case – Chidozie Nnachor May 19 '19 at 00:45
129

One that worked for me was:

.+(\\.+)$

Try it online!

Explanation:

.+     - any character except newline
(      - create a group
 \\.+   - match a backslash, and any characters after it
)      - end group
$      - this all has to happen at the end of the string
Jeeter
  • 5,887
  • 6
  • 44
  • 67
  • 35
    Thanks for the break down of the parts :) – MrsPop88 Jan 05 '17 at 12:23
  • 5
    I was specifically looking for a regex that matches the last forward slash(/). Turns out the accepted answer above by @stema does the job when the backslash is replaced with a forward slash. Yours matches everything following EVERY slash, which really isn't the solution sought. I upvoted your answer because your explanation, was succint, although your solution didn't really do the job – Chidozie Nnachor May 19 '19 at 00:44
  • 1
    This is so much simpler and generally better than a negative lookahead, as long as it is uninterrupted on a line, why overcomplicate? – Scott Anderson Jun 29 '20 at 13:32
  • 1
    @ChidozieNnachor, with your case of forward slash, did you place a _single_ forward slash in front of the parentheses, i.e. like `/(.+)`? That works for me, capturing the text after the last forward slash only. If it was failing for you, the difference could be in the used dialect of regular expression. – Vojta F Jan 11 '22 at 13:36
  • @VojtaF, this is too long in the past I really do not remember this anymore. Perhaps I am indeed wrong. – Chidozie Nnachor Jan 12 '22 at 15:00
65

A negative look ahead is a correct answer, but it can be written more cleanly like:

(\\)(?!.*\\)

This looks for an occurrence of \ and then in a check that does not get matched, it looks for any number of characters followed by the character you don't want to see after it. Because it's negative, it only matches if it does not find a match.

TimE
  • 2,800
  • 1
  • 27
  • 25
  • 6
    This matches the last backslash *only*. The OP wants to match everything after it, too. – Alan Moore Jul 09 '16 at 04:13
  • 1
    Very helpful, this cleaner version, although only capturing the backslash, made everything click. Thank you. – Matt Binford Dec 20 '19 at 21:31
  • This solution worked for me. I wanted to get the last occurrence of which need not to be at the end of line. – Rehan Anis May 12 '22 at 14:07
  • This helped me resolve my goal - I was looking for a match on only last patter of a 5 digit sequence. ([0-9]{5})(?!.*[0-9]{5}) - I understand this to mean, 5 digits - not followed by 5 digits while considering the entire string. Thank you. – Dre Day Jun 28 '22 at 14:20
32

You can try anchoring it to the end of the string, something like \\[^\\]*$. Though I'm not sure if one absolutely has to use regexp for the task.

Michael Krelin - hacker
  • 138,757
  • 24
  • 193
  • 173
  • 2
    This worked great for me. `([^\/]*)$` matches the file name in a path for a Linux box. Can you explain how the caret `^` works in this context? I have only ever used it for signifying the beginning of strings. – Brad Jun 23 '14 at 01:21
  • @Brad, it's negation. Meaning `[^\/]` matches any character except for `/`. – Michael Krelin - hacker Jun 23 '14 at 06:23
12

What about this regex: \\[^\\]+$

SERPRO
  • 10,015
  • 8
  • 46
  • 63
  • Well I don't think that need to be in the regex. But I'll edit my answer – SERPRO Dec 04 '11 at 19:35
  • err... I don't think it should be regex at all, but certainly for match to include it, it should be in. Not that it matters, I've just thought of what could be wrong about your answer after seeing it was downvoted and this was what I came up with, so I commented. – Michael Krelin - hacker Dec 04 '11 at 19:53
  • @michael, don't get me wrong I appreciate your comment, I just thought it's no necessary to add it on the regex the \ ;) – SERPRO Dec 04 '11 at 21:49
11

If you don't want to include the backslash, but only the text after it, try this: ([^\\]+)$ or for unix: ([^\/]+)$

Katja
  • 727
  • 8
  • 8
4

I used below regex to get that result also when its finished by a \

(\\[^\\]+)\\?$

[Regex Demo]

shA.t
  • 16,580
  • 5
  • 54
  • 111