25
\$\begingroup\$

Your challenge is to find the file extension of a provided filename:

hi.txt -> txt or .txt
carrot.meme -> meme or .meme
lol (undefined behavior)
what..is..this..file -> file or .file
.bashrc -> bashrc or .bashrc
[email protected][]h -> h0wC[]h or .h0wC[]h
agent.000 -> 000 or .000

You must get the text from the last . or after the last . to the end of the string. The first capturing group match of the regular expression /\.([^.]+)$/ works, and so does splitting the input on .s and returning the last one.

The file name will always contain at least one ., but it may contain multiple .. (see examples)

The input will always match ^[.a-zA-Z0-9^!\[\]{}@$%+=]+$.

\$\endgroup\$
7
  • 20
    \$\begingroup\$ Please consider using the Sandbox in the future to get feedback on your challenges before posting them to the main site. \$\endgroup\$
    – user45941
    Commented May 16, 2017 at 20:45
  • 1
    \$\begingroup\$ codegolf.meta.stackexchange.com/a/12432/59376 - Got this idea from your challenge. \$\endgroup\$ Commented May 16, 2017 at 21:51
  • \$\begingroup\$ @carusocomputing nice challenge! \$\endgroup\$
    – user58826
    Commented May 17, 2017 at 0:06
  • 2
    \$\begingroup\$ why the negative votes? Is this challenge "exceedingly trivial" or so ? \$\endgroup\$
    – Abel Tom
    Commented May 17, 2017 at 5:09
  • \$\begingroup\$ @AbelTom edit history would suggest downvotes were for the lack of specifications in the first draft of this question. \$\endgroup\$ Commented May 17, 2017 at 5:12

104 Answers 104

2
\$\begingroup\$

JS (ES6), 26 25 bytes

x=>/\.([^.]+)$/.exec(x)[1]

-1 byte thanks to Shaggy

document.querySelector('pre').innerText = (x=>/\.([^.]+)$/.exec(x)[1])("example.txt")
<input oninput = "document.querySelector('pre').innerText = (x=>x.match(/\.([^.]+)$/)[1])(this.value)" value = "example.txt">
<pre></pre>

Alternate, 29 bytes:

x=>(y=x.split`.`)[y.length-1]
\$\endgroup\$
1
  • \$\begingroup\$ Rulw seem allow x=>/\.[^.]+$/.exec(x) \$\endgroup\$
    – l4m2
    Commented Mar 15, 2018 at 19:45
2
\$\begingroup\$

K (oK), 6 bytes

Solution:

*|"."\

Try it online!

Examples:

*|"."\"whats.up.txt"
"txt"
  *|"."\"[email protected][]h"
"h0wC[]h"

Explanation:

Split \ the input on ".", reverse | this list, and then take the first * one. K is interpreted right-to-left:

*|"."\ / the solution
  "."\ / "." split (\),
 |     / reverse
*      / first
\$\endgroup\$
2
\$\begingroup\$

Java 8, 52 27 bytes

s->s.replaceAll(".*\\.","")

Try it here.

Replace everything before the last dot (and the dot itself) with nothing.

This is shorter than using split (s->s.split("\\.")[s.split("\\.").length-1];) or substring (s->s.substring(s.lastIndexOf('.'));).

\$\endgroup\$
2
\$\begingroup\$

JavaScript, 21 bytes

x=>x.split('.').pop()

Explanation:

This code takes x.txt and turns it into a array. The last element of the array is the file type. This code uses the pop function to remove the last element. In the process, the pop function returns the last element.

\$\endgroup\$
3
  • \$\begingroup\$ +Dennis, I have turned it into a arrow function. Does this comply with the rules? \$\endgroup\$
    – Aspect
    Commented Mar 13, 2018 at 0:15
  • \$\begingroup\$ Yes, it is fine now. :) By the way, StackExchange uses @ to ping people, not +. \$\endgroup\$
    – Dennis
    Commented Mar 13, 2018 at 0:18
  • 2
    \$\begingroup\$ Save 2 bytes with x=>x.split`.`.pop(). \$\endgroup\$ Commented Mar 14, 2018 at 2:02
2
\$\begingroup\$

Python 3, 46 bytes

-8 bytes thanks to Wheat Wizard and Scrooble

import sys
print(sys.argv[1].split('.')[-1])

EDIT: I fixed the code, and the filename is a command-line argument

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Welcome to the site! This doesn't appear to work, so you should either fix, or delete this answer. \$\endgroup\$ Commented Mar 11, 2018 at 17:55
  • \$\begingroup\$ This works for 54 \$\endgroup\$ Commented Mar 11, 2018 at 17:57
  • \$\begingroup\$ To get the last item of a list you can use -1 as the index instead of len(a)-1. You could also probably change your input format to reduce the number of bytes. \$\endgroup\$
    – Wheat Wizard
    Commented Mar 11, 2018 at 18:21
  • \$\begingroup\$ Adding to WW's suggestion: if you use -1 rather than len(a)-1, you no longer need the assignment and can save quite a few bytes. \$\endgroup\$ Commented Mar 11, 2018 at 21:12
2
\$\begingroup\$

Kotlin, 17 bytes

split(".").last()

Beautified

split(".").last()

Test

data class Test(val input: String, val output: String)

val test = listOf(
        Test("hi.txt", "txt"),
        Test("carrot.meme", "meme"),
        Test("what..is..this..file", "file"),
        Test(".bashrc", "bashrc"),
        Test("[email protected][]h", "h0wC[]h"),
        Test("agent.000", "000")
)

fun String.f() =
split(".").last()

fun main(args: Array<String>) {
    for ((i, o) in test) {
        if (o != i.f()) {
            throw AssertionError()
        }
    }
}

TIO

TryItOnline

\$\endgroup\$
2
\$\begingroup\$

V, 4 bytes

òdt.

Try it online!

Recursively delete everything up to, but not including the next .

\$\endgroup\$
2
\$\begingroup\$

C++, 73 bytes

I'm a bit surprised that no one tried C++, since it's an easy one :

#include<string>
auto e=[](std::string s){return s.substr(s.rfind(46));};

And the code to test ( may have to iostream, initializer_list, and exception ) :

std::initializer_list<std::string> test{
    "hi.txt", // .txt
    "carrot.meme", // .meme
    "lol", // invalid string position
    "what..is..this..file", // .file
    ".bashrc", // .bashrc
    "[email protected][]h", // .h0wC[]h
    "agent.000" // .000
};

for (const auto& a : test) {
    try {
        std::cout << e(a) << '\n';
    }
    catch (std::out_of_range& r) {
        std::cout << "out of range exception : " << r.what() << '\n';
    }
}

And, as you may expect, like compilers, if there's undefined behavior, there's no undefined behavior. If there's no file extension, the function will throw a std::out_of_range exception, as said in cppreference

\$\endgroup\$
2
\$\begingroup\$

SmileBASIC, 45 bytes

INPUT S$@L
E$=POP(S$)+E$ON"."==E$[0]GOTO@L?E$

Outputs extension with the period.

\$\endgroup\$
2
\$\begingroup\$

Turing Machine But Way Worse, 1315 1287 bytes

0 0 0 1 1 0 0
1 0 1 1 8 0 0
0 1 0 1 2 0 0
1 1 1 1 9 0 0
0 2 0 1 3 0 0
1 2 1 1 a 0 0
0 3 0 1 4 0 0
1 3 1 1 b 0 0
0 4 0 1 5 0 0
1 4 1 1 c 0 0
0 5 0 1 6 0 0
1 5 1 1 d 0 0
0 6 0 1 7 0 0
1 6 1 1 e 0 0
0 7 0 1 f 0 0
1 7 1 1 0 0 0
0 8 0 1 9 0 0
1 8 1 1 9 0 0
0 9 0 1 a 0 0
1 9 1 1 a 0 0
0 a 0 1 b 0 0
1 a 1 1 b 0 0
0 b 0 1 c 0 0
1 b 1 1 c 0 0
0 c 0 1 d 0 0
1 c 1 1 d 0 0
0 d 0 1 e 0 0
1 d 1 1 e 0 0
0 e 0 1 0 0 0
1 e 1 1 0 0 0
0 f 0 0 g 0 0
1 f 1 0 g 0 0
0 g 0 0 h 0 0
1 g 1 0 p 0 0
0 h 0 0 q 0 0
1 h 1 0 i 0 0
0 i 0 0 r 0 0
1 i 1 0 j 0 0
0 j 0 0 s 0 0
1 j 1 0 k 0 0
0 k 0 0 l 0 0
1 k 1 0 t 0 0
0 l 0 0 u 0 0
1 l 1 0 m 0 0
0 m 0 0 n 0 0
1 m 1 0 v 0 0
0 n 0 0 o 0 0
1 n 1 0 g 0 0
0 p 0 0 q 0 0
1 p 1 0 q 0 0
0 q 0 0 r 0 0
1 q 1 0 r 0 0
0 r 0 0 s 0 0
1 r 1 0 s 0 0
0 s 0 0 t 0 0
1 s 1 0 t 0 0
0 t 0 0 u 0 0
1 t 1 0 u 0 0
0 u 0 0 f 0 0
1 u 1 0 f 0 0
0 o 0 1 w 0 0
1 o 1 1 w 0 0
0 w 0 1 x 0 0
1 w 1 1 E 0 0
0 x 0 1 y 0 0
1 x 1 1 F 0 0
0 y 0 1 z 0 0
1 y 1 1 G 0 0
0 z 0 1 A 0 0
1 z 1 1 H 0 0
0 A 0 1 B 0 0
1 A 1 1 I 0 0
0 B 0 1 C 0 0
1 B 1 1 J 0 0
0 C 0 1 D 0 0
1 C 1 1 K 0 0
0 D 0 1 D 0 1
1 D 1 1 w 1 0
0 E 0 1 F 0 0
1 E 1 1 F 0 0
0 F 0 1 G 0 0
1 F 1 1 G 0 0
0 G 0 1 H 0 0
1 G 1 1 H 0 0
0 H 0 1 I 0 0
1 H 1 1 I 0 0
0 I 0 1 J 0 0
1 I 1 1 J 0 0
0 J 0 1 K 0 0
1 J 1 1 K 0 0
0 K 0 1 w 1 0
1 K 1 1 w 1 0

Try it online!

Wow, this is big.

\$\endgroup\$
1
  • \$\begingroup\$ Wow this is incredible! \$\endgroup\$
    – MilkyWay90
    Commented Aug 10, 2019 at 5:47
2
\$\begingroup\$

Befunge-98 (FBBI), 50 bytes

{v
 >~:a`!#v_
--2*86:$<:u-10_v#
02-u0}>:#,_@   >00

Try it online!

Puts string onto stack, then iterates through it in reverse, putting each new character onto new stack. Once a . is encountered, discard original stack and output new stack in 0gnirts format.

\$\endgroup\$
2
\$\begingroup\$

brainfuck, 45 bytes

,[>,]>+[[-]++[<->------]<---<[->+>+<<]>]>[.>]

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Setanta, 66 34 bytes

gniomh(s){toradh roinn@s(".")[-1]}

Try it here!

\$\endgroup\$
2
\$\begingroup\$

Arn, 6 bytes

Ê^!⁺╔d

Try it!

Explained

Unpacked: :!".":}

    _ Variable initialized to STDIN; implied
  :! Split on
    "." String containing a period
:} Tail
\$\endgroup\$
2
+100
\$\begingroup\$

APL (Dyalog Unicode), 10 bytes (SBCS)

⊃∘⌽'.'∘≠⊆⊢

-7 bytes after Bubbler's suggestion.

Try it online!

APL (Dyalog Unicode), 17 bytes (SBCS)

⊃⌽'.'(1↓¨,⊂⍨⊣=,)⍞

Explanation

⊃⌽'.'(1↓¨,⊂⍨⊣=,)⍞
                ⍞ string input
            ⊣=,)  get characters, evaluate if they are equal to the left arg '.'
         ,⊂⍨      enclose each part after a dot
  '.'(1↓¨         drop each dot in the strings
 ⌽                reverse the split string array
⊃                 take the first value

Try it online!

\$\endgroup\$
5
  • \$\begingroup\$ Including the dot is allowed (so you don't need 1↓¨), but then, you can use ≠⊆⊢ idiom to split the words at dots, excluding dots. \$\endgroup\$
    – Bubbler
    Commented Aug 28, 2020 at 7:11
  • \$\begingroup\$ Then the tacit ⊃∘⌽'.'∘≠⊆⊢ is one byte shorter than full program ⊃⌽'.'(≠⊆⊢)⍞. \$\endgroup\$
    – Bubbler
    Commented Aug 28, 2020 at 7:20
  • \$\begingroup\$ interesting. I'll try it out. How do it get it to work on TIO? \$\endgroup\$
    – Razetime
    Commented Aug 28, 2020 at 7:26
  • \$\begingroup\$ No different from other function submissions. \$\endgroup\$
    – Bubbler
    Commented Aug 28, 2020 at 7:35
  • 1
    \$\begingroup\$ Or equally long: ⊃∘⌽⎕NPARTS \$\endgroup\$
    – Adám
    Commented Jun 12, 2021 at 22:17
2
\$\begingroup\$

Python3 (32 bytes)

f=input()
print(f[f.rfind('.'):])

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ Welcome to the site. You might like to include a link to Try it online! in your answer. TIO is widely used here because it's quite handy: not only does it let other people try out your code, it also creates pre-formatted CGCC submissions for you. \$\endgroup\$
    – Dingus
    Commented Aug 29, 2020 at 9:32
2
\$\begingroup\$

8086 Assembly (NASM) + DOS, 262 bytes source, 50 bytes assembled

I'm pretty new to assembly, but I thought I'd give this a try. This is a full DOS program, not just a snippet.

section .bss
b resb 256
org 256
section .text
mov byte[b],254
mov ah,10
mov dx,b
int 33
mov bh,0
mov bl,[b+1]
add bx,b+2
mov bp,bx
l:sub bx,1
cmp byte[bx],46
jne l
mov byte[bx],10
p:mov ah,2
mov dl,[bx]
int 33
add bx,1
cmp bx,bp
jb p
int 32

Essentially, it reads a line of text into a buffer, seeks the end, then seeks backwards until it reaches a .. Then it just prints the rest of the string from that point on. I wasn't able to use DOS's built-in print function, though, since that uses $ as the end-of-string character, which the prompt says is a valid character for the extension itself.

Here is the hexdump of the assembled binary:

00000000  c6 06 34 01 fe 88 e4 ba  34 01 cd 21 b7 00 8a 1e
00000010  35 01 81 c3 36 01 89 dd  83 eb 01 80 3f 2e 75 f8
00000020  c6 07 0a b4 02 8a 17 cd  21 83 c3 01 39 eb 72 f3
00000030  cd 20
\$\endgroup\$
2
\$\begingroup\$

33 v1.0, 13 bytes

The behaviour of the y operator was changed in v1.1, so this program no longer works

Gets the file name passed as an argument and prints the extension (without leading '.') to standard output.

1bt'.'ywmcbtp

Explanation:

1b            (Gets the second item in argv, the filename input)
  t'.'y       (Splits that by '.')
       wmcb   (Gets the last element in the list)
           tp (Prints to standard output)
\$\endgroup\$
2
\$\begingroup\$

Vyxal, 4 bytes

\.€t

Try it Online! (Test cases!)

Splits on spaces and outputs the tail.

\$\endgroup\$
2
\$\begingroup\$

MATL, 8 7 bytes

46&YbO)

Try it at MATL Online!

Explanation

        % Implicitly grab input as string
46      % ASCII for '.'
&Yb     % Split the input string at the '.' characters
O)      % Retrieve just the last part
        % Implicitly print the result
\$\endgroup\$
2
\$\begingroup\$

C (gcc), 50 bytes

p;char*f(char*s){for(;*s;)p=*s++^46?p:s;return p;}

Try it online!

C (gcc), 45 bytes skipping return

p;char*f(char*s){for(;*s;)p=*s++^46?p:s;s=p;}

Try it online!

C (gcc), 24 bytes by ceilingcat

#define f(s)rindex(s,46)

Try it online!

\$\endgroup\$
0
1
\$\begingroup\$

Python 2, 25 bytes

lambda s:s.split('.')[-1]

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Brain-Flak, 84 bytes

Includes +2 for -rc

(()){{}([((((()()()){}())()){}{}){}]({}<>)<>)({()(<{}>)}{})}{}{{}}<>{}{({}<>)<>}<>

Try it online!

# Push 1 to start the loop
(())

# Start loop
{{}

  # If TOS == 46 i.e. '.'
  ([((((()()()){}())()){}{}){}]({}<>)<>)({()(<{}>)}{})
  # ^------------------------^ ^-------^ 
  #           This is 46         Also, copy TOS to other stack

# End loop after the first '.'
}{}

# Delete everything from this stack
{{}}

# Delete the '.' that got copied
<>{}

# Copy everything back to reverse it to the correct order
{({}<>)<>}<>
\$\endgroup\$
1
\$\begingroup\$

Japt, 6 5 bytes

q'. o

Try it online!

Explanation

 q'. o
Uq'. o
Uq'.    # Split the input at "."
     o # Return the last item
\$\endgroup\$
1
  • \$\begingroup\$ When you only need to return the last item of an array, you can use o in place of gJ. (Learned that trick from @obarakon a while back) \$\endgroup\$ Commented May 16, 2017 at 23:38
1
\$\begingroup\$

jq, 15 14 characters

(11 10 characters code + 4 characters command line options.)

./"."|last

Sample run:

bash-4.4$ jq -Rr './"."|last' <<< 'what..is..this..file'
file

On-line test

\$\endgroup\$
1
\$\begingroup\$

Octave, 24 bytes

@(x)strsplit(x,'.'){end}

Creates an anonymous function named ans which can accept a string as input

Online Demo

\$\endgroup\$
1
\$\begingroup\$

Pyth, 5 bytes

ecz\.

try it here

\$\endgroup\$
1
\$\begingroup\$

Charcoal, 6 4 bytes

-2 bytes thanks to Erik the Outgolfer

⊟⪪S.

Try it online!

Explanation

⊟      Pop
  ⪪ .  Split on "."
   S  Next input as string
       Implicit print of value
\$\endgroup\$
1
  • \$\begingroup\$ Can't you use ⊟x instead of §x±¹? \$\endgroup\$ Commented May 17, 2017 at 13:13
1
\$\begingroup\$

REXX 53

parse value reverse(arg(1)) with e "." 
say reverse(e)
\$\endgroup\$
1
\$\begingroup\$

C#, 35 bytes

s=>s.Substring(s.LastIndexOf("."));

Try it online!

\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.