Rest of the path

3

Consider this file path:

C:/Users/Martin/Desktop/BackupFiles/PC1/images/cars/new.png

Your goal is to write a program that will return the file path starting from the folder after the last folder that contains a number till the filename. So, for the above file path, the program should return images/cars/new.png.

One or more of the folder names may also contain spaces:

C:/Users/User1/Documents/Books/eBooks/PM2.4/ref/Project Management.pdf

should return ref/Project Management.pdf.

Also this filepath:

C:/Users/John/Videos/YouTube/3D/Animations/52.Tricky.Maneuvers/video234.png

should return video234.png.

Your answer should work with the above given three examples and all other examples that match the criteria described here.

This is , so the answer with the lowest number of bytes yields victory.

I am new to the site, so feel free to modify my post and/or add relevant tags.

Wais Kamal

Posted 2018-09-14T15:44:17.630

Reputation: 195

1@Stephen "challenge proposer". – user202729 – 2018-09-14T15:52:41.667

Suggested test case: C:/Users/User1a/Documents/foo.pdf. (Can you confirm that the expected output is Documents/foo.pdf in that case?) And welcome to PPCG! – Arnauld – 2018-09-14T15:53:08.920

Sorry @Stephen, I forgot to mention that. As per the example given, you should start from the last folder that contains a number in its name. I will also modify the question so that there are three examples. – Wais Kamal – 2018-09-14T15:56:44.473

3Do we have to support some weird Unicode characters like ߈ ("NKO DIGIT EIGHT") and would it be considered a number? – user202729 – 2018-09-14T16:00:50.850

What if the "part" after the last folder with a digit is the file name not a folder? (example C:\a1\a.pdf) – user202729 – 2018-09-14T16:02:00.303

No, numbers are 0,1,2,3,4,5,6,7,8,9 and 0. – Wais Kamal – 2018-09-14T16:03:03.030

C:\a1\a.pdf should return a.pdf. – Wais Kamal – 2018-09-14T16:03:30.377

Yes @arnuld, this is the required output from your path. – Wais Kamal – 2018-09-14T16:07:20.567

1@WaisKamal are backslashes considered legitimate path separators? – hidefromkgb – 2018-09-14T16:09:13.550

4I'm not clear on why the third test case is supposed to return Animations/52.Tricky.Maneuvers/video234.png as opposed to video234.png. Why does the folder 52.Tricky.Maneuvers not count as " the last folder that contains a number"? – mypetlion – 2018-09-14T16:22:10.597

2I agree with @mypetlion. 52.Tricky.Maneuvers contains a digit, so shouldn't it output video234.png instead? And if you mean by "starting from the folder after the last folder that contains a number till the filename" that there should always be at least one folder (regardless if it contains digits) before the file-path, doesn't that mean that C:\a1\a.pdf should output C:\a1\a.pdf?.. – Kevin Cruijssen – 2018-09-14T16:52:20.520

1As per the example given, you should start from the last folder that contains a number in its name.. This is not what your third example suggests. However, this is what your second example does. So, what's the correct one? – DimChtz – 2018-09-14T17:16:20.790

@mypetlion (challenge fixed) – user202729 – 2018-09-15T13:15:20.717

Um, does our code need to work with something else than the provided three examples? "Your answer should work with the above given three examples." If it should only work for the three examples, that's highly discouraged. – Erik the Outgolfer – 2018-09-18T14:45:28.790

These are just examples, so the answer must work as specified in the question. – Wais Kamal – 2018-09-18T18:13:53.953

Answers

1

Retina, 9 bytes

.*\d.*?/

Regex is ported from @Arnauld's JavaScript answer, so make sure to upvote him!

Try it online.

Explanation:

.*\d.*?/    # Main regex:
.*          #  Zero or more characters (as much as possible)
  \d        #  Followed by a digit
    .*?     #  Followed by zero or more optional characters (as few as possible)
       /    #  Followed by a slash

            # Replace the match with:
            #  Nothing (so basically remove that leading part)

Kevin Cruijssen

Posted 2018-09-14T15:44:17.630

Reputation: 67 575

Don't worry, I upvoted all correct answers :) – Wais Kamal – 2018-09-18T14:34:51.510

5

JavaScript (ES6), 29 28 bytes

Saved 1 byte thanks to @tsh

s=>s.replace(/.*\d.*?\//,'')

Try it online!

How?

                                             /.*\d.*?\//
                                              \/\/\_/\/
                                              | |  | |
match the longest possible string (greedy) ---+ |  | |
match a digit ----------------------------------+  | |
match the shortest possible string (lazy) ---------+ |
match a slash ---------------------------------------+

Arnauld

Posted 2018-09-14T15:44:17.630

Reputation: 111 334

So, why not s=>s.replace(/.*\d.*?\//,'')? – tsh – 2018-09-16T08:18:11.017

@tsh Because I didn't realize it would be 1 byte shorter. :p Thanks! – Arnauld – 2018-09-16T08:46:27.163

4

sed, 17 bytes

s:.*[0-9][^/]*/::

Try it online.

hidefromkgb

Posted 2018-09-14T15:44:17.630

Reputation: 211

4

Gema, 8 bytes

*<D>*\/=

Sample run:

bash-4.4$ gema '*<D>*\/=' <<< 'C:/Users/Martin/Desktop/BackupFiles/PC1/images/cars/new.png'
images/cars/new.png

bash-4.4$ gema '*<D>*\/=' <<< 'C:/Users/User1/Documents/Books/eBooks/PM2.4/ref/Project Management.pdf'
ref/Project Management.pdf

bash-4.4$ gema '*<D>*\/=' <<< 'C:/Users/John/Videos/YouTube/3D/Animations/52.Tricky.Maneuvers/video234.png'
video234.png

Try it online!

manatwork

Posted 2018-09-14T15:44:17.630

Reputation: 17 865

Can you please add a Try It Online link? I am not familiar with Gema.

– Wais Kamal – 2018-09-17T14:24:30.683

Sorry, unfortunately there is no Gema or GeL interpreter on TIO. ☹ – manatwork – 2018-09-17T14:28:11.130

Requested. – Jonathan Allan – 2018-09-17T20:40:18.923

3

Powershell 42 39 45 30 26 bytes

Find the last decimal before a /, fetch all after the slash as the new path

($args-split'.*\d.*?/')[1]

Try it out!


- many bytes by tips from @mazzy
- 1 byte by removing non-required regex escape
- 4 bytes as the regex with -split didn't require a group
- added greedy decimal search

Edwin

Posted 2018-09-14T15:44:17.630

Reputation: 71

Great! I think $args is better then param($f)$f – mazzy – 2018-09-14T18:15:13.853

1Completely right, although using $args within an expression always seems to return the original value, powershell might think of it as an array with ToString() or something. Works fine with indexer though. – Edwin – 2018-09-14T19:23:31.257

"$args". Welcome to Tips for golfing in PowerShell

– mazzy – 2018-09-14T21:07:18.930

The script return 2 values: $true/$false from -match expression and match string. I think should return the file path means the file path only. I beleave it can be golfed more. – mazzy – 2018-09-14T21:11:03.337

Included both solutions. Up to @Wais Kamal which output matches the criteria. – Edwin – 2018-09-15T08:01:12.490

$v= is shorter then >$null :) and try a -split instead -match. – mazzy – 2018-09-15T08:09:09.603

1split had a lot of additional perks :) – Edwin – 2018-09-15T14:10:05.337

Cool! and... fatality... Finish it! ($args-split'.*\d.*?/')[1] :) – mazzy – 2018-09-15T16:34:56.863

port of Javascript by @tsh $args-replace'.*\d.*?/'. Welcome to PPCG! – mazzy – 2018-09-16T15:50:02.480

2

Python 2, 74 bytes

r='';k=1
for c in input():
 r+=c;k-=c.isdigit()
 if'/'==c:r*=k;k=1
print r

Try it online!


Python 2, 42 bytes

lambda n:re.sub(".*\d.*?/","",n)
import re

Try it online!

ovs

Posted 2018-09-14T15:44:17.630

Reputation: 21 408

2

Java (JDK 10), 26 bytes

s->s.split(".*\\d.*?/")[1]

Try it online!

Olivier Grégoire

Posted 2018-09-14T15:44:17.630

Reputation: 10 647

1

Matlab, 68 bytes

function[r]=f(s),[~,b]=regexp(s,'/[^/;]+\d[^/;]+/');r=s(b+1:end);end

Try it Online!

DimChtz

Posted 2018-09-14T15:44:17.630

Reputation: 916

1

Jelly, 16 bytes

”/ɓṣṖf€ØDTṀ‘ṫ@ṣj

A monadic Link accepting a list of characters which returns a list of characters.

Try it online!

How?

”/ɓṣṖf€ØDTṀ‘ṫ@ṣj - Link: list of characters X
”/               - literal '/' character
  ɓ              - start a new dyadic chain with swapped arguments - i.e. f(X,'/')
   ṣ             - split (X) at ('/')
    Ṗ            - pop (removes the rightmost)
       ØD        - yield digit characters
      €          - for each: (of the parts of X after the split & pop)
     f           -   filter keep (digit characters)
         T       - truthy indices (1-indexed indices of parts containing any digit(s))
          Ṁ      - maximum (rightmost, zero if not found)
           ‘     - increment
              ṣ  - split (X) at ('/') (...again)
             @   - with swapped arguments:
            ṫ    -   tail (the split X) from index (the incremented maximum...)
               j - join with ('/')

Jonathan Allan

Posted 2018-09-14T15:44:17.630

Reputation: 67 804

1

Red, 79 bytes

func[s][d: charset"0123456789"parse s[any[to d thru"/"]copy t to end(print t)]]

Try it online!

Galen Ivanov

Posted 2018-09-14T15:44:17.630

Reputation: 13 815

1

Pyth, 14 bytes

The same regex solution that everybody else is using:

:z"^.*\d.*?/""

:                     regex replace
 z                    in the input() string
  "^.*\d.*?/"         the file path up until the last path with a number
             "        with an empty string (Pyth terminates this string at end of program)

Venerax

Posted 2018-09-14T15:44:17.630

Reputation: 21

1

05AB1E, 23 bytes

'/©¡RćUηí®ýʒþd_}®«õš¤X«

Try it online or verify all test cases.

05AB1E has no regexes, so this is not the kind of challenge it will do very good, in comparison to non-verbose languages that have a strength in regexes like Retina or Pyth.
Can probably still be golfed by at least a few bytes, though.

Explanation:

'/              # Push a "/"
  ©             # Store it in the register (without popping)
   ¡            # Split the (implicit) input on slashes
                #  i.e. "C:/Desktop3/Stuff/F0/images/new1.png"
                #   → ["C:","Desktop3","Stuff","F0","images","new1.png"]
    R           # Reverse this list
                #  i.e. ["C:","Desktop3","Stuff","F0","images","new1.png"]
                #   → ["new1.png","images","F0","Stuff","Desktop3","C:"]
     ć          # Head extracted
                #  i.e. ["new1.png","images","F0","Stuff","Desktop3","C:"]
                #   → ["images","F0","Stuff","Desktop3","C:"] and "new1.png"
      U         # Pop the extracted head, and store it in variable `X`
       η        # Take the prefixes of the list
                #  i.e. ["images","F0","Stuff","Desktop3","C:"]
                #   → [["images"],["images","F0"],["images","F0","Stuff"],["images","F0","Stuff","Desktop3"],["images","F0","Stuff","Desktop3","C:"]]
        í       # Reverse each inner list again
                #  i.e. [["images"],["images","F0"],["images","F0","Stuff"],["images","F0","Stuff","Desktop3"],["images","F0","Stuff","Desktop3","C:"]]
                #   → [["images"],["F0","images"],["Stuff","F0","images"],["Desktop3","Stuff","F0","images"],["C:","Desktop3","Stuff","F0","images"]]
         ®ý     # And join them by slashes
                #  i.e. [["images"],["F0","images"],["Stuff","F0","images"],["Desktop3","Stuff","F0","images"],["C:","Desktop3","Stuff","F0","images"]]
                #   → ["images","F0/images","Stuff/F0/images","Desktop3/Stuff/F0/images","C:/Desktop3/Stuff/F0/images"]
ʒ   }           # Now filter this list by:
 þ              #  Leave only the digits of this suffix
                #   i.e. "images" → ""
                #   i.e. "Stuff/F0/images" → 0
  d             #  Check if its >= 0
                #   i.e. "" → 0 (falsey)
                #   i.e. 0 → 1 (truthy)
   _            #  Inverse the boolean (0→1; 1→0)
     ®«         # Append a slash to each remaining suffix
                #  i.e. ["images"] → ["images/"]
       õš       # Prepend an empty string as list
                # (work-around when there are no valid suffices left)
                #  i.e. [] → [""]
                #  i.e. ["images/"] → ["","images/"]
         ¤      # Take the last suffix
                #  i.e. ["","images/"] → "images/"
          X«    # Append variable `X` (and implicitly output the result)
                #  i.e. "images/" and "new1.png" → "images/new1.png"

Kevin Cruijssen

Posted 2018-09-14T15:44:17.630

Reputation: 67 575

1

Ruby, 22 bytes

->s{s=~/.*\d.*?\//;$'}

Try it online!

Same trick as Arnauld and everybody else after him.

G B

Posted 2018-09-14T15:44:17.630

Reputation: 11 099

0

Pip, 12 bytes

a@`\d.*?/`$'

Takes input as a command-line argument. Verify all test cases: Try it online!

Explanation

Does not use the same regex as everyone else! (Well, okay, it's pretty similar.)

a             1st command-line argument
  `\d.*?/`    Regex matching a digit, as few characters as possible, and then a slash
 @            Find all matches
          $'  Special variable: the portion of the string after the last match
              Autoprint

The shortest solutions using the standard regex were all 13 bytes:

aRM`.*\d.*?/`   Remove
a|>`.*\d.*?/`   Left-strip
aR`.*\d.*?/`x   Replace with empty string

DLosc

Posted 2018-09-14T15:44:17.630

Reputation: 21 213