File extension is in extensions list: Difference between revisions

Added Easylang
(→‎{{header|Fortran}}: Follow the new requirements.)
(Added Easylang)
 
(97 intermediate revisions by 48 users not shown)
Line 1:
{{draft task}} [[Category:File_System_Operations]] [[Category:String_manipulation]]
[[Category:String_manipulation]]
 
{{task}}
[[wp:Filename extension|Filename extensions]] are a rudimentary but commonly used way of identifying files types.
 
{{task heading}}
 
;Task:
Given an arbitrary filename and a list of extensions, tell whether the filename has one of those extensions.
 
 
Notes:
Line 14 ⟶ 17:
 
;''Extra credit:''
: Allow extensions to contain dots. This way, users of your function/program have full control over what they consider as the extension in cases like <code>archive.tar.gz</code>.:
<big>archive.tar.gz</big>
: Please state clearly whether or not your solution does this.
 
Line 21 ⟶ 25:
The following test cases all assume this list of extensions: &nbsp; <code>zip</code>, <code>rar</code>, <code>7z</code>, <code>gz</code>, <code>archive</code>, <code>A##</code>
 
:::::::: {| class="wikitable"
|-
! Filename
Line 41 ⟶ 45:
If your solution does the extra credit requirement, add <code>tar.bz2</code> to the list of extensions, and check the following additional test cases:
 
:::::::: {| class="wikitable"
|-
! Filename
Line 53 ⟶ 57:
{{task heading|Motivation}}
 
Checking if a file is in a certain category of file formats with known extensions (e.g. archive files, or image files) is a common problem in practice, and may be approached differently thanfrom extracting and outputting an arbitrary extension ''(see e.g. <code>FileNameExtensionFilter</code> in Java)''.
 
It also requires less assumptions about the format of an extension, because the calling code can decide what extensions are valid.
Line 59 ⟶ 63:
For these reasons, this task exists in addition to the [[Extract file extension]] task.
 
{{task heading|Related tasks}}
 
;Related tasks:
* [[Extract file extension]]
* [[String matching]]
<br><br>
 
=={{header|11l}}==
<hr>
{{trans|Python}}
 
<syntaxhighlight lang="11l">F is_ext(file_name, extensions)
R any(extensions.map(e -> @file_name.lowercase().ends_with(‘.’e.lowercase())))
 
F test(file_names, extensions)
L(file_name) file_names
print(file_name.ljust(max(file_names.map(f_n -> f_n.len)))‘ ’String(is_ext(file_name, extensions)))
 
test([‘MyData.a##’, ‘MyData.tar.Gz’, ‘MyData.gzip’, ‘MyData.7z.backup’, ‘MyData...’, ‘MyData’], [‘zip’, ‘rar’, ‘7z’, ‘gz’, ‘archive’, ‘A##’, ‘tar.bz2’])
test([‘MyData_v1.0.tar.bz2’, ‘MyData_v1.0.bz2’], [‘tar.bz2’])</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## 1B
MyData.tar.Gz 1B
MyData.gzip 0B
MyData.7z.backup 0B
MyData... 0B
MyData 0B
MyData_v1.0.tar.bz2 1B
MyData_v1.0.bz2 0B
</pre>
 
=={{header|Action!}}==
<syntaxhighlight lang="action!">DEFINE PTR="CARD"
 
CHAR FUNC ToLower(CHAR c)
IF c>='A AND c<='Z THEN
c==+'a-'A
FI
RETURN (c)
 
BYTE FUNC CheckExt(CHAR ARRAY file,ext)
BYTE i,j
CHAR c1,c2
 
i=file(0) j=ext(0)
IF i<j THEN RETURN (0) FI
 
WHILE j>0
DO
c1=ToLower(file(i))
c2=ToLower(ext(j))
IF c1#c2 THEN RETURN (0) FI
i==-1
j==-1
OD
IF file(i)#'. THEN
RETURN (0)
FI
RETURN (1)
 
BYTE FUNC Check(CHAR ARRAY file PTR ARRAY exts BYTE count)
BYTE i
 
FOR i=0 TO count-1
DO
IF CheckExt(file,exts(i)) THEN
RETURN (1)
FI
OD
RETURN (0)
 
PROC Main()
PTR ARRAY exts(7),files(8)
BYTE i
 
exts(0)="zip"
exts(1)="rar"
exts(2)="7z"
exts(3)="gz"
exts(4)="archive"
exts(5)="A##"
exts(6)="tar.bz2"
 
files(0)="MyData.a##"
files(1)="MyData.tar.Gz"
files(2)="MyData.gzip"
files(3)="MyData.7z.backup"
files(4)="MyData..."
files(5)="MyData"
files(6)="MyData_v1.0.tar.bz2"
files(7)="MyData_v1.0.bz2"
 
FOR i=0 to 7
DO
Print(files(i)) Print(" -> ")
IF Check(files(i),exts,7) THEN
PrintE("true")
ELSE
PrintE("false")
FI
OD
RETURN</syntaxhighlight>
{{out}}
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/File_extension_is_in_extensions_list.png Screenshot from Atari 8-bit computer]
<pre>
MyData.a## -> true
MyData.tar.Gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO;
with Ada.Strings.Fixed.Equal_Case_Insensitive; use Ada.Strings.Fixed;
with Ada.Strings.Bounded;
 
procedure Main is
 
package B_String is new Ada.Strings.Bounded.Generic_Bounded_Length (30);
use B_String;
function is_equal (left, right : String) return Boolean renames
Ada.Strings.Fixed.Equal_Case_Insensitive;
 
type extension_list is array (Positive range <>) of Bounded_String;
Ext_List : extension_list :=
(To_Bounded_String ("zip"), To_Bounded_String ("rar"),
To_Bounded_String ("7z"), To_Bounded_String ("gz"),
To_Bounded_String ("archive"), To_Bounded_String ("A##"),
To_Bounded_String ("tar.bz2"));
type filename_list is array (Positive range <>) of Bounded_String;
fnames : filename_list :=
(To_Bounded_String ("MyData.a##"), To_Bounded_String ("MyData.tar.Gz"),
To_Bounded_String ("MyData.gzip"), To_Bounded_String ("MyData..."),
To_Bounded_String ("Mydata"), To_Bounded_String ("MyData_V1.0.tar.bz2"),
To_Bounded_String ("MyData_v1.0.bz2"));
Valid_Extension : Boolean;
begin
for name of fnames loop
Valid_Extension := False;
Put (To_String (name));
for ext of Ext_List loop
declare
S : String := "." & To_String (ext);
T : String := Tail (Source => To_String (name), Count => S'Length);
begin
if is_equal (S, T) then
Valid_Extension := True;
end if;
end;
end loop;
Set_Col (22);
Put_Line (": " & Valid_Extension'Image);
end loop;
end Main;</syntaxhighlight>
{{out}}
<pre>
MyData.a## : TRUE
MyData.tar.Gz : TRUE
MyData.gzip : FALSE
MyData... : FALSE
Mydata : FALSE
MyData_V1.0.tar.bz2 : TRUE
MyData_v1.0.bz2 : FALSE
</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
<syntaxhighlight lang="algol68"># returns the length of str #
OP LENGTH = ( STRING str )INT: ( UPB str - LWB str ) + 1;
# returns TRUE if str ends with ending FALSE otherwise #
PRIO ENDSWITH = 9;
OP ENDSWITH = ( STRING str, STRING ending )BOOL:
IF INT str length = LENGTH str;
INT ending length = LENGTH ending;
ending length > str length
THEN
# the ending is longer than the string #
FALSE
ELSE
# the string is at least as long as the ending #
str[ ( str length - ending length ) + 1 : AT 1 ] = ending
FI # ENDSWITH # ;
# returns str cnverted to upper case #
OP TOUPPER = ( STRING str )STRING:
BEGIN
STRING result := str;
FOR s pos FROM LWB result TO UPB result DO
result[ s pos ] := to upper( result[ s pos ] )
OD;
result
END # TOUPPER # ;
# tests whether file name has one of the extensions and returns #
# the index of the extension in extensions or LWB extensions - 1 #
# if it does not end with one of the extensions #
# the tests are not case-sensitive #
PROC has extension in list = ( STRING file name, []STRING extensions )INT:
BEGIN
INT extension number := LWB extensions - 1;
STRING upper name = TOUPPER file name;
FOR pos FROM LWB extensions TO UPB extensions WHILE extension number < LWB extensions DO
IF upper name ENDSWITH ( "." + TOUPPER extensions[ pos ] )
THEN
# found the extension #
extension number := pos
FI
OD;
extension number
END # has extension # ;
# test the has extension in list procedure #
PROC test has extension in list = ( STRING file name, []STRING extensions, BOOL expected result )VOID:
IF INT extension number = has extension in list( file name, extensions );
extension number < LWB extensions
THEN
# the file does not have one of the extensions #
print( ( file name
, " does not have an extension in the list "
, IF expected result THEN "NOT AS EXPECTED" ELSE "" FI
, newline
)
)
ELSE
# the file does have one of the extensions #
print( ( file name
, " has extension """
, extensions[ extension number ]
, """ "
, IF NOT expected result THEN "NOT AS EXPECTED" ELSE "" FI
, newline
)
)
FI # test has extension in list # ;
# the extensions for the task #
[]STRING task extensions = ( "zip", "rar", "7z", "gz", "archive", "A##" );
# test the file names in the standard task #
test has extension in list( "MyData.a##", task extensions, TRUE );
test has extension in list( "MyData.tar.Gz", task extensions, TRUE );
test has extension in list( "MyData.gzip", task extensions, FALSE );
test has extension in list( "MyData.7z.backup", task extensions, FALSE );
test has extension in list( "MyData...", task extensions, FALSE );
test has extension in list( "MyData", task extensions, FALSE );
# the extensions for the extra credit #
[]STRING ec extensions = ( "zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2" );
# test the file names in the extra credit #
test has extension in list( "MyData_v1.0.tar.bz2", ec extensions, TRUE );
test has extension in list( "MyData_v1.0.bz2", ec extensions, FALSE )</syntaxhighlight>
{{out}}
<pre>
MyData.a## has extension "A##"
MyData.tar.Gz has extension "gz"
MyData.gzip does not have an extension in the list
MyData.7z.backup does not have an extension in the list
MyData... does not have an extension in the list
MyData does not have an extension in the list
MyData_v1.0.tar.bz2 has extension "tar.bz2"
MyData_v1.0.bz2 does not have an extension in the list</pre>
 
=={{header|APL}}==
{{works with|Dyalog APL}}
<syntaxhighlight lang="apl">ext←{
ex←⎕C'.',¨⍺
ex∨.≡(-≢¨ex)↑¨⊂⎕C⍵
}
 
test←{
e←'zip' 'rar' '7z' 'gz' 'archive' 'A##' 'tar.bz2'
f←'MyData.a##' 'MyData.tar.Gz' 'MyData.gzip' 'MyData.7z.backup'
f,←'MyData...' 'MyData' 'MyData_v1.0.tar.bz2' 'MyData_V1.0.bz2'
f,[1.5]e∘ext¨f
}</syntaxhighlight>
{{out}}
<pre> MyData.a## 1
MyData.tar.Gz 1
MyData.gzip 0
MyData.7z.backup 0
MyData... 0
MyData 0
MyData_v1.0.tar.bz2 1
MyData_V1.0.bz2 0</pre>
 
=={{header|Arturo}}==
<syntaxhighlight lang="rebol">fileExtensions: map ["zip" "rar" "7z" "gz" "archive" "A##"] => ["." ++ lower &]
hasExtension?: function [file][
in? extract.extension lower file
fileExtensions
]
files: ["MyData.a##" "MyData.tar.Gz" "MyData.gzip" "MyData.7z.backup" "MyData..." "MyData"]
 
loop files 'file ->
print [file "=> hasExtension?:" hasExtension? file]</syntaxhighlight>
{{out}}
 
<pre>MyData.a## => hasExtension?: true
MyData.tar.Gz => hasExtension?: true
MyData.gzip => hasExtension?: false
MyData.7z.backup => hasExtension?: false
MyData... => hasExtension?: false
MyData => hasExtension?: false</pre>
 
=={{header|AutoHotkey}}==
<syntaxhighlight lang="autohotkey">
fileList := "MyData.a##,MyData.tar.Gz,MyData.gzip,MyData.7z.backup,MyData...,MyData,MyData_v1.0.tar.bz2,MyData_v1.0.bz2"
extList := "zip,rar,7z,gz,archive,A##,tar.bz2"
textOut := "File extension is in list (" extList ") ?`n"
loop,parse,fileList,CSV
{
textOut .= A_LoopField " ---> "
lastDotPos := InStr(A_LoopField,".",0,0)
extloop := SubStr(A_LoopField,lastDotPos+1)
if (extloop = "bz2")
{
lastDotPos := InStr(A_LoopField,".",0,0,2)
extloop := SubStr(A_LoopField,lastDotPos+1)
}
if !lastDotPos or !extloop
textOut .= "NO`n"
else if extloop in %extList%
textOut .= "YES`n"
else
textOut .= "NO`n"
}
MsgBox % textOut
ExitApp
</syntaxhighlight>
{{Out}}
<pre>File extension is in list (zip,rar,7z,gz,archive,A##,tar.bz2) ?
MyData.a## ---> YES
MyData.tar.Gz ---> YES
MyData.gzip ---> NO
MyData.7z.backup ---> NO
MyData... ---> NO
MyData ---> NO
MyData_v1.0.tar.bz2 ---> YES
MyData_v1.0.bz2 ---> NO</pre>
 
=={{header|AWK}}==
 
This solution meets the extended criteria stated in the problem.
{{update|AWK}}
 
<syntaxhighlight lang="awk">
<lang AWK>
# syntax: GAWK -f FILE_EXTENSION_IS_IN_EXTENSIONS_LIST.AWK
BEGIN {
n = split("txtzip,gzrar,bat7z,cgz,c++archive,exeA##,pdftar.bz2", arr, ",")
for (i=1; i<=n; i++) {
ext_arr[tolower(arr[i])] = ""
}
filenames = "c:,txt,textMyData.txta##,text.TXT,testMyData.tar.gzGz,test/test2MyData.exegzip,test,fooMyData.c,foo7z.Cbackup,fooMyData..C++,foo.c#,fooMyData,MyData_v1.zkl0.tar.bz2,documentMyData_v1.0.pdfbz2"
n = split(filenames, fn_arr, ",")
print(" EXT FILENAME")
for (i=1; i<=n; i++) {
extext_found = ""
iffor (fn_arr[i]ext ~in /\./ext_arr) {
ext =if (tolower(fn_arr[i]) ~ (".*\\." ext "$")) {
while (match(ext,/\./) >ext_found 0)= {ext
ext = substr(ext,RSTART+1)break
}
}
ans = (extext_found in== ext_arr"") ? "trueis not in list" : ("falseis in list: " ext_found)
printf("%-5ss %-5sextension %s\n",ans,ext, fn_arr[i], ans)
}
exit(0)
}</syntaxhighlight>
}
</lang>
{{out}}
<pre>
MyData.a## extension is in list: a##
EXT FILENAME
MyData.tar.Gz extension is in list: gz
false c:
MyData.gzip extension is not in list
false txt
MyData.7z.backup extension is not in list
true txt text.txt
MyData... extension is not in list
true txt text.TXT
MyData extension is not in list
true gz test.tar.gz
MyData_v1.0.tar.bz2 extension is in list: tar.bz2
true exe test/test2.exe
MyData_v1.0.bz2 extension is not in list
false test
</pre>
true c foo.c
 
true c foo.C
 
true c++ foo.C++
=={{header|BASIC}}==
false c# foo.c#
==={{header|BASIC256}}===
false zkl foo.zkl
{{trans|FreeBASIC}}
true pdf document.pdf
<syntaxhighlight lang="basic256">arraybase 1
dim extensions$ = {".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"}
 
dim filenames$ = {"MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup", "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"}
 
#dim as integer n, m
#dim as boolean flag
 
for n = 1 to filenames$[?]
flag = False
for m = 1 to extensions$[?]
if right(filenames$[n], length(extensions$[m])) = extensions$[m] then
flag = True
print filenames$[n]; " -> "; extensions$[m]; " -> "; " true"
exit for
end if
next m
if flag = False then print filenames$[n]; " -> "; "false"
next n
end</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
==={{header|FreeBASIC}}===
<syntaxhighlight lang="freebasic">Dim As String extensions(1 To 7) => {".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"}
 
Dim As String filenames(1 To 8) => {"MyData.a##", "MyData.tar.gz", _
"MyData.gzip", "MyData.7z.backup", "MyData...", "MyData", _
"MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"}
 
Dim As Integer n, m
Dim As Boolean flag
 
For n = 1 To Ubound(filenames)
flag = False
For m = 1 To Ubound(extensions)
If Right(filenames(n), Len(extensions(m))) = extensions(m) Then
flag = True
Print filenames(n); " -> "; extensions(m); " -> "; " true"
Exit For
End If
Next m
If flag = False Then Print filenames(n); " -> "; "false"
Next n
Sleep</syntaxhighlight>
{{out}}
<pre>MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false</pre>
 
==={{header|QBasic}}===
{{works with|QBasic}}
{{works with|QuickBasic}}
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">DIM extensions$(7)
FOR i = 1 TO 7
READ d$: extensions$(i) = d$
NEXT i
 
DIM filenames$(8)
FOR i = 1 TO 8
READ d$: filenames$(i) = d$
NEXT i
 
FOR n = 1 TO UBOUND(filenames$)
flag = 0
FOR m = 1 TO UBOUND(extensions$)
IF RIGHT$(filenames$(n), LEN(extensions$(m))) = extensions$(m) THEN
flag = 1
PRINT filenames$(n); " -> "; extensions$(m); " -> "; " true"
EXIT FOR
END IF
NEXT m
IF flag = 0 THEN PRINT filenames$(n); " -> "; "false"
NEXT n
END
 
DATA ".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"
DATA "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
DATA "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"</syntaxhighlight>
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
==={{header|True BASIC}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">DIM extensions$(7)
FOR i = 1 TO 7
READ d$
LET extensions$(i) = d$
NEXT i
DIM filenames$(8)
FOR i = 1 TO 8
READ d$
LET filenames$(i) = d$
NEXT i
FOR n = 1 TO UBOUND(filenames$)
LET flag = 0
FOR m = 1 TO UBOUND(extensions$)
IF (filenames$(n))[LEN(filenames$(n))-LEN(extensions$(m))+1:maxnum] = extensions$(m) THEN
LET flag = 1
PRINT filenames$(n); " -> "; extensions$(m); " -> "; " true"
EXIT FOR
END IF
NEXT m
IF flag = 0 THEN PRINT filenames$(n); " -> "; "false"
NEXT n
 
DATA ".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"
DATA "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
DATA "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"
END</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
==={{header|Yabasic}}===
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">dim extensions$(7)
for i = 1 to 7
read d$: extensions$(i) = d$
next i
 
dim filenames$(8)
for i = 1 to 8
read d$: filenames$(i) = d$
next i
 
for n = 1 to arraysize(filenames$(),1)
flag = 0
for m = 1 to arraysize(extensions$(),1)
if right$(filenames$(n), len(extensions$(m))) = extensions$(m) then
flag = 1
print filenames$(n), " -> ", extensions$(m), " -> ", " true"
break
end if
next m
if flag = 0 then print filenames$(n), " -> ", "false" : fi
next n
end
 
data ".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"
data "MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup"
data "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de FreeBASIC.
</pre>
 
 
=={{header|Batch File}}==
This solution does '''not''' contain support for dots in extension names.
<syntaxhighlight lang="dos">
@echo off
setlocal enabledelayedexpansion
 
set "extensions=.zip .rar .7z .gz .archive .A##"
 
:loop
if "%~1"=="" exit /b
set onlist=0
 
for %%i in (%extensions%) do if /i "%~x1"=="%%i" set onlist=1
 
if %onlist%==1 (
echo Filename: "%~1" ^| Extension: "%~x1" ^| TRUE
) else (
echo Filename: "%~1" ^| Extension: "%~x1" ^| FALSE
)
 
shift
goto loop
</syntaxhighlight>
{{out}}
<pre>
Filename: "MyData.a##" | Extension: ".a##" | TRUE
Filename: "MyData.tar.Gz" | Extension: ".Gz" | TRUE
Filename: "MyData.gzip" | Extension: ".gzip" | FALSE
Filename: "MyData.7z.backup" | Extension: ".backup" | FALSE
Filename: "MyData..." | Extension: "" | FALSE
Filename: "MyData" | Extension: "" | FALSE
</pre>
 
=={{header|C}}==
 
===C: dots allowed ===
{{update|C}}
There is no magic in extensions: they are just trailing characters in names.
<syntaxhighlight lang="c">/*
* File extension is in extensions list (dots allowed).
*
* This problem is trivial because the so-called extension is simply the end
* part of the name.
*/
 
#define _CRT_SECURE_NO_WARNINGS
 
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <locale.h>
#include <string.h>
 
#ifdef _Bool
#include <stdbool.h>
#else
#define bool int
#define true 1
#define false 0
#endif
 
/*
* The implemented algorithm is not the most efficient one: for N extensions
* of length M it has the cost O(N * M).
*/
int checkFileExtension(char* fileName, char* fileExtensions)
{
char* fileExtension = fileExtensions;
 
if ( *fileName )
{
while ( *fileExtension )
{
int fileNameLength = strlen(fileName);
int extensionLength = strlen(fileExtension);
if ( fileNameLength >= extensionLength )
{
char* a = fileName + fileNameLength - extensionLength;
char* b = fileExtension;
while ( *a && toupper(*a++) == toupper(*b++) )
;
if ( !*a )
return true;
}
fileExtension += extensionLength + 1;
}
}
return false;
}
 
void printExtensions(char* extensions)
{
while( *extensions )
{
printf("%s\n", extensions);
extensions += strlen(extensions) + 1;
}
}
 
bool test(char* fileName, char* extension, bool expectedResult)
{
bool result = checkFileExtension(fileName,extension);
bool returnValue = result == expectedResult;
printf("%20s result: %-5s expected: %-5s test %s\n",
fileName,
result ? "true" : "false",
expectedResult ? "true" : "false",
returnValue ? "passed" : "failed" );
return returnValue;
}
 
int main(void)
{
static char extensions[] = ".zip\0.rar\0.7z\0.gz\0.archive\0.A##\0.tar.bz2\0";
 
setlocale(LC_ALL,"");
 
printExtensions(extensions);
printf("\n");
 
if ( test("MyData.a##", extensions,true )
&& test("MyData.tar.Gz", extensions,true )
&& test("MyData.gzip", extensions,false)
&& test("MyData.7z.backup", extensions,false)
&& test("MyData...", extensions,false)
&& test("MyData", extensions,false)
&& test("MyData_v1.0.tar.bz2",extensions,true )
&& test("MyData_v1.0.bz2", extensions,false)
&& test("filename", extensions,false)
)
printf("\n%s\n", "All tests passed.");
else
printf("\n%s\n", "Last test failed.");
 
printf("\n%s\n", "press enter");
getchar();
return 0;
}</syntaxhighlight>
{{out}}
<pre>
.zip
.rar
.7z
.gz
.archive
.A##
.tar.bz2
 
MyData.a## result: true expected: true test passed
MyData.tar.Gz result: true expected: true test passed
MyData.gzip result: false expected: false test passed
MyData.7z.backup result: false expected: false test passed
MyData... result: false expected: false test passed
MyData result: false expected: false test passed
MyData_v1.0.tar.bz2 result: true expected: true test passed
MyData_v1.0.bz2 result: false expected: false test passed
filename result: false expected: false test passed
 
 
All tests passed.
 
press enter
</pre>
 
===C: another solution ===
According to this, an extension is whatever comes after the '''last''' dot. Dotless filename won't match anything.
 
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <string.h>
#include <stdbool.h>
Line 187 ⟶ 840:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C++}}==
This solution allows extensions to contain dots.
<syntaxhighlight lang="cpp">#include <algorithm>
#include <cctype>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
 
bool endsWithIgnoreCase(const std::string& str, const std::string& suffix) {
const size_t n1 = str.length();
const size_t n2 = suffix.length();
if (n1 < n2)
return false;
return std::equal(str.begin() + (n1 - n2), str.end(), suffix.begin(),
[](char c1, char c2) {
return std::tolower(static_cast<unsigned char>(c1))
== std::tolower(static_cast<unsigned char>(c2));
});
}
 
bool filenameHasExtension(const std::string& filename,
const std::vector<std::string>& extensions) {
return std::any_of(extensions.begin(), extensions.end(),
[&filename](const std::string& extension) {
return endsWithIgnoreCase(filename, "." + extension);
});
}
 
void test(const std::string& filename,
const std::vector<std::string>& extensions) {
std::cout << std::setw(20) << std::left << filename
<< ": " << std::boolalpha
<< filenameHasExtension(filename, extensions) << '\n';
}
 
int main() {
const std::vector<std::string> extensions{"zip", "rar", "7z",
"gz", "archive", "A##", "tar.bz2"};
test("MyData.a##", extensions);
test("MyData.tar.Gz", extensions);
test("MyData.gzip", extensions);
test("MyData.7z.backup", extensions);
test("MyData...", extensions);
test("MyData", extensions);
test("MyData_v1.0.tar.bz2", extensions);
test("MyData_v1.0.bz2", extensions);
return 0;
}</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## : true
MyData.tar.Gz : true
MyData.gzip : false
MyData.7z.backup : false
MyData... : false
MyData : false
MyData_v1.0.tar.bz2 : true
MyData_v1.0.bz2 : false
</pre>
 
=={{header|Clojure}}==
<syntaxhighlight lang="clojure">(defn matches-extension [ext s]
(re-find (re-pattern (str "\\." ext "$"))
(clojure.string/lower-case s)))
 
(defn matches-extension-list [ext-list s]
(some #(matches-extension % s) ext-list))</syntaxhighlight>
 
It is assumed that when extensions are "added to the system", they will be "normalized" to the expected (lower) case.
 
<syntaxhighlight lang="clojure">(defn normalize-extensions [ext-list]
(map clojure.string/lower-case ext-list))</syntaxhighlight>
 
{{out}}
<pre>
(def ext-list ["zip" "rar" "7z" "gz" "archive" "A##" "tar.bz2"])
 
(def exts (normalize-extensions ext-list))
 
(map (partial matches-extension-list exts)
["MyData.a##"
"MyData.tar.Gz"
"MyData.gzip"
"MyData.7z.backup"
"MyData..."
"MyData"
"MyData_v1.0.tar.bz2"
"MyData_v1.0.bz2"])
 
(".a##" ".gz" nil nil nil nil ".tar.bz2" nil)
</pre>
 
=={{header|D}}==
===Variant 1===
<syntaxhighlight lang="d">
import std.stdio;
import std.string;
import std.range;
import std.algorithm;
 
void main()
{{update|D}}
{
auto exts = ["zip", "rar", "7z", "gz", "archive", "A##"];
auto filenames = ["MyData.a##",
"MyData.tar.Gz",
"MyData.gzip",
"MyData.7z.backup",
"MyData...",
"MyData"];
 
writeln("extensions: ", exts);
<lang d>void main() {
writeln;
import std.stdio, std.string, std.path, std.algorithm;
 
foreach(filename; filenames)
immutable exts = [".txt", ".gz", ".bat", ".c", ".c++", ".exe", ".pdf"];
{
string extension = filename.drop(filename.lastIndexOf(".") + 1).toLower;
 
bool found;
immutable fileNames =
foreach(ext; exts)
"text.txt
text.TXT{
if (extension == ext.toLower)
test.tar.gz
test/test2.exe {
found = true;
test\\test2.exe
test break;
a/b/c\\d/foo }
foo.c}
 
foo.C
writeln(filename, " : ", found);
foo.C++
}
foo.c#
 
foo.zkl
 
document.pdf";
</syntaxhighlight>
 
foreach (fName; fileNames.split)
writeln(fName, ": ", exts.canFind(fName.extension.toLower));
}</lang>
{{out}}
<pre>text.txt: true
extensions: ["zip", "rar", "7z", "gz", "archive", "A##"]
text.TXT: true
 
test.tar.gz: true
test/test2MyData.exea## : true
test\test2MyData.exetar.Gz : true
testMyData.gzip : false
a/b/c\d/fooMyData.7z.backup : false
MyData... : false
foo.c: true
MyData : false
foo.C: true
 
foo.C++: true
</pre>
foo.c#: false
 
foo.zkl: false
 
document.pdf: true</pre>
===Variant 2===
<syntaxhighlight lang="d">
import std.stdio;
import std.string;
import std.range;
import std.algorithm;
 
void main()
{
auto exts = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"];
auto filenames = ["MyData.a##",
"MyData.tar.Gz",
"MyData.gzip",
"MyData.7z.backup",
"MyData...",
"MyData",
"MyData_v1.0.tar.bz2",
"MyData_v1.0.bz2"];
 
writeln("extensions: ", exts);
 
writeln;
foreach(filename; filenames)
{
bool found;
foreach(ext; exts)
{
if (filename.toLower.endsWith("." ~ ext.toLower))
{
found = true;
break;
}
}
 
writeln(filename, " : ", found);
}
 
}
 
</syntaxhighlight>
 
{{out}}
<pre>
extensions: ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]
 
MyData.a## : true
MyData.tar.Gz : true
MyData.gzip : false
MyData.7z.backup : false
MyData... : false
MyData : false
MyData_v1.0.tar.bz2 : true
MyData_v1.0.bz2 : false
 
</pre>
=={{header|Delphi}}==
{{libheader| System.SysUtils}}
{{Trans|D}}
<syntaxhighlight lang="delphi">
program File_extension_is_in_extensions_list;
 
{$APPTYPE CONSOLE}
 
uses
System.SysUtils;
 
const
exts: TArray<string> = ['zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2'];
filenames: TArray<string> = ['MyData.a##', 'MyData.tar.Gz', 'MyData.gzip',
'MyData.7z.backup', 'MyData...', 'MyData', 'MyData_v1.0.tar.bz2', 'MyData_v1.0.bz2'];
 
begin
write('extensions: [');
for var ext in exts do
begin
write(ext, ' ');
end;
writeln(']'#10);
 
for var filename in filenames do
begin
var found := false;
for var ext in exts do
if (filename.toLower.endsWith('.' + ext.toLower)) then
begin
found := True;
Break;
end;
writeln(filename: 20, ' : ', found);
end;
 
readln;
end.</syntaxhighlight>
{{out}}
<pre>extensions: [zip rar 7z gz archive A## tar.bz2 ]
 
MyData.a## : TRUE
MyData.tar.Gz : TRUE
MyData.gzip : FALSE
MyData.7z.backup : FALSE
MyData... : FALSE
MyData : FALSE
MyData_v1.0.tar.bz2 : TRUE
MyData_v1.0.bz2 : FALSE</pre>
 
=={{header|EasyLang}}==
{{trans|BASIC256}}
<syntaxhighlight>
exts$[] = [ ".zip" ".rar" ".7z" ".gz" ".archive" ".a##" ".tar.bz2" ]
fnames$[] = [ "MyData.a##" "MyData.tar.gz" "MyData.gzip" "MyData.7z.backup" "MyData..." "MyData" "MyData_v1.0.tar.bz2" "MyData_v1.0.bz2" ]
for fn$ in fnames$[]
ext$ = ""
for ext$ in exts$[]
h = len ext$
if substr fn$ (len fn$ - h + 1) h = ext$
print fn$ & " -> " & ext$ & " -> true"
break 1
.
.
if ext$ = ""
print fn$ & " -> false"
.
.
</syntaxhighlight>
{{out}}
<pre>
MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|Factor}}==
This solution allows dots in file extensions.
<syntaxhighlight lang="factor">USING: formatting kernel qw sequences splitting unicode ;
IN: rosetta-code.file-extension-list
 
CONSTANT: extensions qw{ zip rar 7z gz archive A## tar.bz2 }
CONSTANT: filenames qw{
MyData.a## MyData.tar.Gz MyData.gzip MyData.7z.backup
MyData... MyData MyData_v1.0.tar.bz2 MyData_v1.0.bz2
}
 
: ext-in-list? ( filename list -- ? )
[ >lower "." split ] dup [ map ] curry bi*
[ tail? t = ] with find nip >boolean ;
 
extensions "List of file extensions: %[%s, %]\n\n" printf
"File extension in extensions list?\n" printf
filenames [
dup extensions ext-in-list? "%19s %u\n" printf
] each</syntaxhighlight>
{{out}}
<pre>
List of file extensions: { zip, rar, 7z, gz, archive, A##, tar.bz2 }
 
File extension in extensions list?
MyData.a## t
MyData.tar.Gz t
MyData.gzip f
MyData.7z.backup f
MyData... f
MyData f
MyData_v1.0.tar.bz2 t
MyData_v1.0.bz2 f
</pre>
 
=={{header|Fortran}}==
The plan is to use the extractor function for file name extensions that was defined in [[Extract_file_extension#Fortran|another problem]] to obtain the extension's text, then use that text to index a character string of approved extensions. These are defined with the period included, but no extension's text can include a period - all start with a period and continue with letters or digits only - so the specification of a list of such items need not mess about with quotes and commas and so forth. The deed is done via function EXTIN(FNAME,LIST), but there is a lot of support stuff in the absence of an existing library to call upon.
 
When the task was revised to include a # as a possible character in the file name extension part, the scan in FEXT that allowed only certain characters via GOODEXT required changing. One possibility was to increase the size of GOODEXT so as to encompass the three characters in ODDITIES, that includes a #. But it also includes a : (all this is from a different context) and in file names, under DOS, this character is special. So, all-in-all, it seemed better to retreat from exclusions and simply allow all characters, as per the original specification. This done, the function EXTIN that checked that the extension was one of a specified set seemed no longer restricted to file name extensions, so instead it became FOUND(TEXT,LIST) and the period, the only special character now, is used as the delimiter in LIST.
Line 238 ⟶ 1,169:
Petty details include the list employing capitals only, as the match is to not distinguish capital from lower case letters, so in the usual way the candidate extension's text is converted to capitals. The list could be subjected to UPCASE, but it is bad form to damage what might be a constant, and one possibly in read-only storage at that. An internal working copy could be made which would then be fed to UPCASE, except that this would be a waste on every invocation. A further trick involves appending a period to the candidate text so that for example ".JP" becomes ".JP." - otherwise a ".JP" would be found in the sequence ".JPG" which would be wrong, so as a result, the list of texts must have a period appended to its last entry, otherwise it would not be findable. Again, this could be done internally, via <code>INDEX(LIST//".",EXT(1:L)//".")</code> at a run-time cost.
 
Some systems supply an UPCASE (or similar name) to convert text that hopefully would run faster than this example, which relies on searching for the position in a list of letters. A very common alternative is to calculate using character code numerical values, via something like<langsyntaxhighlight Fortranlang="fortran"> IT = ICHAR(TEXT(I:I)) - ICHAR("a") !More symbols precede "a" than "A".
IF (IT.GE.0 .AND. IT.LE.25) TEXT(I:I) = CHAR(IT + ICHAR("A")) !In a-z? Convert!</langsyntaxhighlight> except that this relies on the letters having contiguous character codes, and in EBCDIC they don't - other symbols are mixed in. (Honest!) Faster still would be to use the character code to index an array of 256 pre-computed values.
 
A final annoyance is the presence of trailing spaces because character variables are of fixed size and so must be made "surely long enough" for the longest expectation. This may not cause trouble on output as spaces look just as blank as blank space, but they may well cause trouble in the internal tests. Thus integer function LSTNB reports the last non-blank, and so a test text can be presented with no trailing spaces, as in TEST(I)(1:LSTNB(TEST(I))) or similar. With Fortran 2003, there is a facility for redefining the sizes of character variables on-the-fly so that this problem can be evaded.
 
The MODULE protocol is employed for the convenience of not having to respecify the type of the functions in every calling routine, and also to facilitate the collection of types of characters. Otherwise, prior to F90 there would have to be various COMMON statements, or routines would each simply respecify whatever character sets they needed.<langsyntaxhighlight Fortranlang="fortran"> MODULE TEXTGNASH !Some text inspection.
CHARACTER*10 DIGITS !Integer only.
CHARACTER*11 DDIGITS !With a full stop masquerading as a decimal point.
Line 379 ⟶ 1,310:
END DO !On to the next.
END
</syntaxhighlight>
</lang>
The previous results were when only "image" style files were approved. The approval is no longer so restrictive.
<pre>
Line 401 ⟶ 1,332:
Similarly, the scan of a file name to find the extension part relies on no extension containing a period. If the caller were to determine the text of the extension (rather than using FEXT, which stops with the rightmost period) then whatever results could be presented to function FOUND without difficulty.
 
Users of Windows systems may have the option "Hide extensions for known file types" unticked, but even so, "shortcut" files will not have their file name extension of <code>.lnk</code> shown...
=={{header|Haskell}}==
 
=={{updateheader|HaskellGo}}==
This allows extensions to include a dot and, in the case of success, displays the extension matched (ignoring case) in the list. In the case of failure, the actual (minimum) file extension is displayed.
<syntaxhighlight lang="go">package main
 
import (
"fmt"
"strings"
)
 
var extensions = []string{"zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"}
 
func fileExtInList(filename string) (bool, string) {
filename2 := strings.ToLower(filename)
for _, ext := range extensions {
ext2 := "." + strings.ToLower(ext)
if strings.HasSuffix(filename2, ext2) {
return true, ext
}
}
s := strings.Split(filename, ".")
if len(s) > 1 {
t := s[len(s)-1]
if t != "" {
return false, t
} else {
return false, "<empty>"
}
} else {
return false, "<none>"
}
}
 
func main() {
fmt.Println("The listed extensions are:")
fmt.Println(extensions, "\n")
tests := []string{
"MyData.a##", "MyData.tar.Gz", "MyData.gzip",
"MyData.7z.backup", "MyData...", "MyData",
"MyData_v1.0.tar.bz2", "MyData_v1.0.bz2",
}
for _, test := range tests {
ok, ext := fileExtInList(test)
fmt.Printf("%-20s => %-5t (extension = %s)\n", test, ok, ext)
}
}</syntaxhighlight>
 
{{out}}
<pre>
The listed extensions are:
[zip rar 7z gz archive A## tar.bz2]
 
MyData.a## => true (extension = A##)
MyData.tar.Gz => true (extension = gz)
MyData.gzip => false (extension = gzip)
MyData.7z.backup => false (extension = backup)
MyData... => false (extension = <empty>)
MyData => false (extension = <none>)
MyData_v1.0.tar.bz2 => true (extension = tar.bz2)
MyData_v1.0.bz2 => false (extension = bz2)
</pre>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
include "NSLog.incl"
 
void local fn DoIt
CFArrayRef extensions = @[@"zip",@"rar",@"7z",@"gz",@"archive",@"A##"]
CFArrayRef filenames = @[@"MyData.a##",@"MyData.tar.Gz",@"MyData.gzip",@"MyData.7z.backup",@"MyData...",@"MyData"]
CFStringRef name
NSLogSetTabInterval( 130 )
for name in filenames
NSLog(@"%@\t",name)
if ( fn ArrayContainsObject( fn ArrayValueForKey( extensions, @"lowercaseString" ), lcase(fn StringPathExtension(name) ) ) )
NSLog(@"true")
else
NSLog(@"false")
end if
next
end fn
 
fn DoIt
 
HandleEvents
</syntaxhighlight>
 
=={{header|Haskell}}==
 
<syntaxhighlight lang="haskell">import Data.List
<lang Haskell>
import Data.List
import qualified Data.Char as Ch
 
Line 413 ⟶ 1,429:
 
isExt :: String -> [String] -> Bool
isExt filename extensions = any (`elem` (tails . toLower $ filename)) $ map toLower extensions</syntaxhighlight>
</lang>
 
The code defining isExt could be done point free:
<syntaxhighlight lang="haskell">isExt filename = any (`elem` (tails . toLower $ filename)) . map toLower</syntaxhighlight>
<lang Haskell>
isExt filename = any (`elem` (tails . toLower $ filename)) . map toLower
</lang>
 
Overcoming the one-liner urge on behalf of being more comprehensible would give:
<syntaxhighlight lang="haskell">isExt filename extensions = any (`elem` allTails) lowerExtensions
<lang Haskell>
isExt filename extensions = any (`elem` allTails) lowerExtensions
where allTails = tails . toLower $ filename
lowerExtensions = map toLower extensions</syntaxhighlight>
</lang>
 
Given definition handles composite extensions as well.
=={{header|J}}==
 
'''Testing:'''
{{update|J}}
 
<syntaxhighlight lang="haskell">main = mapM_ (\f -> putStr(f ++ "\t") >> print (f `isExt` extensions)) files
where
files = [ "MyData.a##"
, "MyData.tar.Gz"
, "MyData.gzip"
, "MyData.7z.backup"
, "MyData..."
, "MyData"
, "MyData_v1.0.tar.bz2"
, "MyData_v1.0.bz2" ]
extensions = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]</syntaxhighlight>
{{Out}}
<pre>λ> main
MyData.a## True
MyData.tar.Gz True
MyData.gzip True
MyData.7z.backup False
MyData... False
MyData False
MyData_v1.0.tar.bz2 True
MyData_v1.0.bz2 False</pre>
 
 
We can also express this directly in terms of the '''isSuffix''' function, taking care not to reproduce the small glitch in the draft above, which shows a false positive for '''zip''' in '''.gzip''' (see task description bullet 2).
 
<syntaxhighlight lang="haskell">import Data.Char (toLower)
import Data.List (find, isSuffixOf)
import Data.Maybe (fromMaybe)
 
----------- FILE EXTENSION IS IN EXTENSIONS LIST ---------
 
extensionFound :: [String] -> String -> Maybe String
extensionFound xs fp = find (`isSuffixOf` fp) $ ('.' :) <$> xs
 
 
-------------------------- TESTS -------------------------
main :: IO ()
main =
putStrLn $
fTable
"Any matching extensions found:\n"
id
(fromMaybe "n/a")
(extensionFound
(lowerCased ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]))
(lowerCased
[ "MyData.a##"
, "MyData.tar.Gz"
, "MyData.gzip"
, "MyData.7z.backup"
, "MyData..."
, "MyData"
, "MyData_v1.0.tar.bz2"
, "MyData_v1.0.bz2"
])
 
------------------------- STRINGS ------------------------
fTable :: String -> (a -> String) -> (b -> String) -> (a -> b) -> [a] -> String
fTable s xShow fxShow f xs =
unlines $
s : fmap (((<>) . rjust w ' ' . xShow) <*> ((" -> " <>) . fxShow . f)) xs
where
rjust n c = drop . length <*> (replicate n c <>)
w = maximum (length . xShow <$> xs)
 
lowerCased :: [String] -> [String]
lowerCased = fmap (fmap toLower)</syntaxhighlight>
{{Out}}
<pre>Any matching extensions found:
 
mydata.a## -> .a##
mydata.tar.gz -> .gz
mydata.gzip -> n/a
mydata.7z.backup -> n/a
mydata... -> n/a
mydata -> n/a
mydata_v1.0.tar.bz2 -> .tar.bz2
mydata_v1.0.bz2 -> n/a</pre>
 
=={{header|J}}==
 
'''Solution:'''
<langsyntaxhighlight lang="j">getExtisSuffix=: }.-~&# = i{:&'@I.@E.'
isExt=: e('.~'&:(tolower,&.>)@[ getExt&([: +.>/ isSuffix&(tolower@>)/) boxopen@])</langsyntaxhighlight>
 
'''Usage:'''
<langsyntaxhighlight lang="j"> Exts=: <;._1 ' .ozip .ijsrar .ij7z gz archive A## tar.pbz2'
TestFiles=: <;._1 ' fooMyData.oa## blabMyData.iJtar.Gz dramMyData.gzip latMyData.P7z.backup winMyData...dll fooMyData MyData_v1.0.tar.bz2 MyData_v1.0.bz2'
Exts isExt TestFiles
1 1 0 10 0 0 1 0</langsyntaxhighlight>
 
=={{header|Java}}==
 
{{update|Java}}
 
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.Arrays;
import java.util.Comparator;
 
Line 479 ⟶ 1,571:
}
}
</syntaxhighlight>
</lang>
{{out}}
<pre>Extensions: [.txt, .gz, , .bat]
Line 493 ⟶ 1,585:
{{works with|Java|6+}}
This version is the same as the main version only replace the definition for <code>extIsIn</code> with:
<langsyntaxhighlight lang="java5">public static boolean extIsIn(String test, String... exts){
for(int i = 0; i < exts.length; i++){
exts[i] = exts[i].replaceAll("\\.", "");
}
return (new FileNameExtensionFilter("extension test", exts)).accept(new File(test));
}</langsyntaxhighlight>
It would be one line if not for the dot requirement. <code>FileNameExtensionFilter</code> requires that the extensions have no dots. It also requires that the extensions contain characters (i.e. not the empty string) so that test would need to be removed.
 
=={{header|JavaScript}}==
 
This solution may not be the most performant but works for most implementations. Allows for dotted extensions, as well.
 
'''NOTE''' String.endsWith() was introduced with ECMAScript 6 (ES6), so that is a minimum requirement of your JS processor
 
<syntaxhighlight lang="javascript">
function fileExtensionInExtensionsList(filename) {
let foundIt = false;
let filenameLC = filename.toLowerCase();
let extensions = ["zip", "rar", "7z", "gz", "archive", "A##" ,"tar.bz2"];
extensions.forEach(extension => {
if (filenameLC.endsWith("." + extension.toLowerCase())) { foundIt = true; }
} );
return foundIt;
}
 
// perform tests below
 
var fileNamesToTest = [
"MyData.a##"
,"MyData.tar.Gz"
,"MyData.gzip"
,"MyData.7z.backup"
,"MyData..."
,"MyData"
,"MyData_v1.0.tar.bz2"
,"MyData_v1.0.bz2"
];
 
fileNamesToTest.forEach(filename => {
console.log(filename + " -> " + fileExtensionInExtensionsList(filename));
});
</syntaxhighlight>
 
{{out}}
(from tests - function returns true or false)
<pre>
MyData.a## -> true
MyData.tar.Gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|jq}}==
Line 506 ⟶ 1,646:
 
{{works with|jq|1.4}}
<langsyntaxhighlight lang="jq"># Input: filename
# Output: if the filename ends with one of the extensions (ignoring case), output that extension; else output null.
# Assume that the list of file extensions consists of lower-case strings, including a leading period.
Line 515 ⟶ 1,655:
| if list | index($ext) then $ext else null end
else null
end;</langsyntaxhighlight>
'''Examples:'''
<langsyntaxhighlight lang="jq">("c:", "txt", "text.txt", "text.TXT", "foo.c", "foo.C++", "document.pdf")
| has_extension([".txt", ".c"]) as $ext
| if $ext then "\(.) has extension \($ext)"
else "\"\(.)\" does not have an admissible file extension"
end</langsyntaxhighlight>
 
{{out}}
<langsyntaxhighlight lang="jq">$ jq -r -n -f File_extension_is_in_extensions_list.jq
"c:" does not have an admissible file extension
"txt" does not have an admissible file extension
Line 531 ⟶ 1,671:
foo.c has extension .c
"foo.C++" does not have an admissible file extension
"document.pdf" does not have an admissible file extension</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
 
<syntaxhighlight lang="julia">isext(filename, extensions) = any(x -> endswith(lowercase(filename), lowercase(x)), "." .* extensions)
 
# Test
extensions = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]
for f in ["MyData.a##", "MyData.tar.Gz", "MyData.gzip", "MyData.7z.backup", "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
@printf("%20s : %5s\n", f, isext(f, extensions))
end</syntaxhighlight>
 
{{out}}
<pre> MyData.a## : true
MyData.tar.Gz : true
MyData.gzip : false
MyData.7z.backup : false
MyData... : false
MyData : false
MyData_v1.0.tar.bz2 : true
MyData_v1.0.bz2 : false</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1
 
/* implicitly allows for extensions containing dots */
fun String.isFileExtensionListed(extensions: List<String>): Boolean {
return extensions.any { toLowerCase().endsWith("." + it.toLowerCase()) }
}
 
fun main(args: Array<String>) {
val extensions = listOf("zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2")
val fileNames = listOf(
"MyData.a##",
"MyData.tar.Gz",
"MyData.gzip",
"MyData.7z.backup",
"MyData...",
"MyData",
"MyData_v1.0.tar.bz2",
"MyData_v1.0.bz2"
)
 
for (fileName in fileNames) {
println("${fileName.padEnd(19)} -> ${fileName.isFileExtensionListed(extensions)}")
}
}</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## -> true
MyData.tar.Gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">-- Data declarations
local extentions = {"zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"}
local testCases = {
"MyData.a##",
"MyData.tar.Gz",
"MyData.gzip",
"MyData.7z.backup",
"MyData...",
"MyData",
"MyData_v1.0.tar.bz2",
"MyData_v1.0.bz2"
}
 
-- Return boolean of whether example has a file extension found in extList
function extMatch (extList, example)
for _, extension in pairs(extList) do
if example:lower():match("%." .. extension:lower() .. "$") then
return true
end
end
return false
end
 
-- Main procedure
for _, case in pairs(testCases) do
print(case .. ": " .. tostring(extMatch(extentions, case)))
end</syntaxhighlight>
{{out}}
<pre>MyData.a##: true
MyData.tar.Gz: true
MyData.gzip: false
MyData.7z.backup: false
MyData...: false
MyData: false
MyData_v1.0.tar.bz2: true
MyData_v1.0.bz2: false</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">ClearAll[CheckExtension]
CheckExtension[fn_String, e : {_String ..}] := StringMatchQ[ToLowerCase[FileExtension[fn]], Alternatives @@ ToLowerCase[e]]
exts = {"zip", "rar", "7z", "gz", "archive", "A##"};
CheckExtension["MyData.a##", exts]
CheckExtension["MyData.tar.gz", exts]
CheckExtension["MyData.gzip", exts]
CheckExtension["MyData.7z.backup", exts]
CheckExtension["MyData..", exts]
CheckExtension["MyData", exts]</syntaxhighlight>
{{out}}
<pre>True
True
False
False
False
False</pre>
 
=={{header|Nim}}==
===Task===
For the task, it is possible to use the “splitFile” procedure from the standard module “os” as it split the extension at the last dot.
 
To build the extension list, we can use a compile time function:
<syntaxhighlight lang="nim">import os, strutils
 
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
"MyData.7z.backup", "MyData...", "MyData"]
 
func buildExtensionList(extensions: varargs[string]): seq[string] {.compileTime.} =
for ext in extensions:
result.add('.' & ext.toLowerAscii())
 
const ExtList = buildExtensionList("zip", "rar", "7z", "gz", "archive", "A##")
 
for fileName in fileNameList:
echo fileName, " → ", fileName.splitFile().ext.toLowerAscii() in ExtList</syntaxhighlight>
 
Another way consists to use “mapIt” from standard module “sequtils”:
<syntaxhighlight lang="nim">import os, sequtils, strutils
 
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
"MyData.7z.backup", "MyData...", "MyData"]
 
const ExtList = mapIt(["zip", "rar", "7z", "gz", "archive", "A##"], '.' & it.toLowerAscii())
 
for fileName in fileNameList:
echo fileName, " → ", fileName.splitFile().ext.toLowerAscii() in ExtList</syntaxhighlight>
 
{{out}}
<pre>MyData.a## → true
MyData.tar.Gz → true
MyData.gzip → false
MyData.7z.backup → false
MyData... → false
MyData → false</pre>
 
===Extra task===
The “splitFile” procedure no longer works in this case. We have to use “endsWith” from the “strutils” module, which changes the logic:
 
<syntaxhighlight lang="nim">import strutils, sequtils
 
let fileNameList = ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
"MyData.7z.backup", "MyData...", "MyData",
"MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
 
const ExtList = mapIt(["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"], '.' & it.toLowerAscii())
 
for fileName in fileNameList:
echo fileName, " → ", ExtList.anyIt(fileName.toLowerAscii().endsWith(it))</syntaxhighlight>
 
{{out}}
<pre>MyData.a## → true
MyData.tar.Gz → true
MyData.gzip → false
MyData.7z.backup → false
MyData... → false
MyData → false
MyData_v1.0.tar.bz2 → true
MyData_v1.0.bz2 → false</pre>
 
=={{header|Objeck}}==
<syntaxhighlight lang="objeck">
class FileExtension {
function : Main(args : String[]) ~ Nil {
files := ["MyData.a##", "MyData.tar.Gz", "MyData.gzip",
"MyData.7z.backup", "MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"];
exts := ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"];
each(i : files) {
HasExt(files[i], exts);
};
}
 
function : HasExt(file : String, exts : String[]) ~ Nil {
full_file := file->ToLower();
each(i : exts) {
full_ext := ".";
full_ext += exts[i]->ToLower();
if(full_file->EndsWith(full_ext)) {
IO.Console->Print(file)->Print(" has extension \"")->Print(exts[i])->PrintLine("\"");
return;
};
};
 
IO.Console->Print(file)->PrintLine(" does not have an extension in the list");
}
}</syntaxhighlight>
 
{{out}}
<pre>MyData.a## has extension "A##"
MyData.tar.Gz has extension "gz"
MyData.gzip does not have an extension in the list
MyData.7z.backup does not have an extension in the list
MyData... does not have an extension in the list
MyData does not have an extension in the list
MyData_v1.0.tar.bz2 has extension "tar.bz2"
MyData_v1.0.bz2 does not have an extension in the list</pre>
 
=={{header|PARI/GP}}==
Line 539 ⟶ 1,893:
The examples were taken from the [[#AWK|AWK]] code.
 
<langsyntaxhighlight lang="parigp">lower(s)=
{
my(v=Vecsmall(s));
Line 561 ⟶ 1,915:
ext=["txt","gz","bat","c","c++","exe","pdf"];
filenames=["c:","txt","text.txt","text.TXT","test.tar.gz","test/test2.exe","test","foo.c","foo.C","foo.C++","foo.c#","foo.zkl","document.pdf"];
select(f -> checkExt(ext, f), filenames)</langsyntaxhighlight>
{{out}}
<pre>%1 = ["text.txt", "text.TXT", "test.tar.gz", "test/test2.exe", "foo.c", "foo.C", "foo.C++", "document.pdf"]</pre>
 
=={{header|Perl 6}}==
 
Does the extra credit requirement.
 
{{trans|Raku}}
<lang perl6>sub check-extension ($filename, *@extensions) {
 
so $filename ~~ /:i '.' @extensions $/
<syntaxhighlight lang="perl">sub check_extension {
}</lang>
my ($filename, @extensions) = @_;
my $extensions = join '|', map quotemeta, @extensions;
scalar $filename =~ / \. (?: $extensions ) $ /xi
}</syntaxhighlight>
 
Testing:
<langsyntaxhighlight perl6lang="perl">my @extensions = <('zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2>');
my @files= <(
'MyData.a##', 'MyData.tar.Gz', 'MyData.gzip', 'MyData.7z.backup MyData... MyData',
'MyData...', 'MyData', 'MyData_v1.0.tar.bz2', 'MyData_v1.0.bz2'
>);
printf "%-19s - %s\n",
say "{$_.fmt: '%-19s'} - {check-extension $_, @extensions}" for @files;</lang>
$_, check_extension($_, @extensions) ? 'true' : 'false'
for @files;</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## - Truetrue
MyData.tar.Gz - Truetrue
MyData.gzip - Falsefalse
MyData.7z.backup - Falsefalse
MyData... - Falsefalse
MyData - Falsefalse
MyData_v1.0.tar.bz2 - Truetrue
MyData_v1.0.bz2 - Falsefalse
</pre>
 
=={{header|PHP}}==
This solution does support the extra credit in the task
 
<syntaxhighlight lang="php">
$allowed = ['zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2'];
$lc_allowed = array_map('strtolower', $allowed);
 
$tests = [
['MyData.a##',true],
['MyData.tar.Gz',true],
['MyData.gzip',false],
['MyData.7z.backup',false],
['MyData...',false],
['MyData',false],
['archive.tar.gz', true]
];
 
foreach ($tests as $test) {
$ext = pathinfo($test[0], PATHINFO_EXTENSION);
if (in_array(strtolower($ext), $lc_allowed)) {
$result = 'true';
} else {
$result = 'false';
}
printf("%20s : %s \n", $test[0],$result);
}
</syntaxhighlight>
{{out}}
MyData.a## : true
MyData.tar.Gz : true
MyData.gzip : false
MyData.7z.backup : false
MyData... : false
MyData : false
archive.tar.gz : true
 
=={{header|Phix}}==
Note there is builtin, however get_file_extension("MyData_v1.0.tar.bz2") yields "bz2", since it scans right-to-left for the '.', and also it also yields "so" for "libglfw.so.3.1" (it saves the "1", and the "3", but when they are all-number it carries on scanning left and replaces if it finds another '.'). So to match the task requirements more precisely we shall write a custom version.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">extensions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">lower</span><span style="color: #0000FF;">({</span><span style="color: #008000;">"zip"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"rar"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"7z"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gz"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"archive"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"A##"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"tar.bz2"</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">get_known_extension</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">filename</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]=</span><span style="color: #008000;">'.'</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">extension</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">lower</span><span style="color: #0000FF;">(</span><span style="color: #000000;">filename</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$])</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">extension</span><span style="color: #0000FF;">,</span><span style="color: #000000;">extensions</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">extension</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #008000;">""</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MyData.a##"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData.tar.Gz"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData.gzip"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData.7z.backup"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData..."</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData_v1.0.tar.bz2"</span><span style="color: #0000FF;">,</span>
<span style="color: #008000;">"MyData_v1.0.bz2"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span>
<span style="color: #000000;">ext</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">get_known_extension</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-20s %-10s %s\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ext</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"true"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"false"</span><span style="color: #0000FF;">}[</span><span style="color: #000000;">2</span><span style="color: #0000FF;">-(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ext</span><span style="color: #0000FF;">,</span><span style="color: #000000;">extensions</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)]})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
MyData.a## a## true
MyData.tar.Gz gz true
MyData.gzip false
MyData.7z.backup false
MyData... false
MyData false
MyData_v1.0.tar.bz2 tar.bz2 true
MyData_v1.0.bz2 false
</pre>
 
=={{header|Python}}==
 
<syntaxhighlight lang="python">
{{update|Python}}
def isExt(fileName, extensions):
return True in map(fileName.lower().endswith, ("." + e.lower() for e in extensions))
</syntaxhighlight>
 
and we could also enrich the return value to a Maybe option type, returning Nothing if no file extension match is found, or Just the particular extension, if a match is found:
 
<syntaxhighlight lang="python">'''Check for a specific set of file extensions'''
 
 
# extensionFound :: [Extension] -> FileName -> Maybe Extension
def extensionFound(xs):
'''Nothing if no matching extension is found,
or Just the extension (drawn from xs, and
a suffix of the filename, immediately following
a dot character).
'''
return lambda fn: find(fn.lower().endswith)(
['.' + x.lower() for x in xs]
)
 
 
# TEST ----------------------------------------------------
# main :: IO ()
def main():
'''Check filenames for a particular set of extensions.'''
 
# checkExtension :: FileName -> Maybe Extension
def checkExtension(fn):
return extensionFound([
'zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2'
])(fn)
 
print(
fTable(__doc__ + ':\n')(str)(str)(
compose(fromMaybe('n/a'))(checkExtension)
)([
'MyData.a##',
'MyData.tar.Gz',
'MyData.gzip',
'MyData.7z.backup',
'MyData...',
'MyData',
'MyData_v1.0.tar.bz2',
'MyData_v1.0.bz2'
])
)
 
 
# GENERIC -------------------------------------------------
 
# Just :: a -> Maybe a
def Just(x):
'''Constructor for an inhabited Maybe (option type) value.'''
return {'type': 'Maybe', 'Nothing': False, 'Just': x}
 
 
# Nothing :: Maybe a
def Nothing():
'''Constructor for an empty Maybe (option type) value.'''
return {'type': 'Maybe', 'Nothing': True}
 
 
# compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
def compose(g):
'''Right to left function composition.'''
return lambda f: lambda x: g(f(x))
 
 
# find :: (a -> Bool) -> [a] -> Maybe a
def find(p):
'''Just the first element in the list that matches p,
or Nothing if no elements match.
'''
def go(xs):
for x in xs:
if p(x):
return Just(x)
return Nothing()
return lambda xs: go(xs)
 
 
# fromMaybe :: a -> Maybe a -> a
def fromMaybe(x):
'''The default value x if mb is Nothing,
or the value contained in mb.
'''
return lambda mb: x if (
mb.get('Nothing')
) else mb.get('Just')
 
 
# DISPLAY -------------------------------------------------
 
# fTable :: String -> (a -> String) ->
# (b -> String) -> (a -> b) -> [a] -> String
def fTable(s):
'''Heading -> x display function -> fx display function ->
f -> xs -> tabular string.
'''
def go(xShow, fxShow, f, xs):
ys = [xShow(x) for x in xs]
w = max(map(len, ys))
return s + '\n' + '\n'.join(map(
lambda x, y: y.rjust(w, ' ') + ' -> ' + fxShow(f(x)),
xs, ys
))
return lambda xShow: lambda fxShow: lambda f: lambda xs: go(
xShow, fxShow, f, xs
)
 
 
# MAIN ---
<lang Python>
if __name__ == '__main__':
import os
main()</syntaxhighlight>
{{Out}}
<pre>Check for a specific set of file extensions:
 
MyData.a## -> .a##
def isExt(filename, extensions):
MyData.tar.Gz -> .gz
return os.path.splitext(filename.lower())[-1] in [e.lower() for e in extensions]
MyData.gzip -> n/a
</lang>
MyData.7z.backup -> n/a
MyData... -> n/a
MyData -> n/a
MyData_v1.0.tar.bz2 -> .tar.bz2
MyData_v1.0.bz2 -> n/a</pre>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
{{update|Racket}}
#lang racket
 
(define extensions '(".zip"
<lang racket>#lang racket/base
".rar"
(require (only-in srfi/13 string-suffix-ci?)
(only-in racket/format ~a)) ".7z"
".gz"
".archive"
".a##"
".tar.bz2"))
 
(define filenames '("MyData.a##"
(define ((in-extensions-list? extns) f)
"MyData.tar.Gz"
(findf (λ (e) (string-suffix-ci? e f)) extns))
"MyData.gzip"
"MyData.7z.backup"
"MyData..."
"MyData"
"MyData_v1.0.tar.bz2"
"MyData_v1.0.bz2"))
 
(define (string-right s n)
(define e.g.-extns '(".txt" ".gz" ".bat" ".c" ".c++" ".exe" ".pdf"))
(if (< (string-length s) n)
(define in-e.g.-extns-list? (in-extensions-list? e.g.-extns))
s
(define file-names
(substring s (- (string-length s) n))))
(list "c:" "txt" "text.txt" "text.TXT" "test.tar.gz" "test/test2.exe"
"test" "foo.c" "foo.C" "foo.C++" "foo.c#" "foo.zkl" "document.pdf"))
 
(for ((fdefine (file-extension-in-list? file-names))f lst)
(let ([lcase (string-downcase f)])
(printf "~a ~a~%" (~a #:width 20 f) (or (in-e.g.-extns-list? f) "[NO EXTENSION]")))</lang>
(ormap (lambda (x) (equal? (string-right lcase (string-length x)) x)) extensions)))
(for ((f (in-list filenames)))
(printf "~a ~a~%" (~a #:width 20 f) (file-extension-in-list? f extensions)))
</syntaxhighlight>
{{out}}
<pre>
<pre>c: [NO EXTENSION]
txtMyData.a## [NO EXTENSION]#t
textMyData.txttar.Gz .txt#t
textMyData.TXTgzip .txt#f
testMyData.tar7z.gzbackup .gz#f
test/test2MyData...exe .exe #f
testMyData [NO EXTENSION]#f
MyData_v1.0.tar.bz2 #t
foo.c .c
fooMyData_v1.C0.bz2 .c#f
</pre>
foo.C++ .c++
 
foo.c# [NO EXTENSION]
=={{header|Raku}}==
foo.zkl [NO EXTENSION]
(formerly Perl 6)
document.pdf .pdf</pre>
 
Does the extra credit requirement.
 
<syntaxhighlight lang="raku" line>sub check-extension ($filename, *@extensions) {
so $filename ~~ /:i '.' @extensions $/
}
 
# Testing:
 
my @extensions = <zip rar 7z gz archive A## tar.bz2>;
my @files= <
MyData.a## MyData.tar.Gz MyData.gzip MyData.7z.backup MyData... MyData
MyData_v1.0.tar.bz2 MyData_v1.0.bz2
>;
say "{$_.fmt: '%-19s'} - {check-extension $_, @extensions}" for @files;</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## - True
MyData.tar.Gz - True
MyData.gzip - False
MyData.7z.backup - False
MyData... - False
MyData - False
MyData_v1.0.tar.bz2 - True
MyData_v1.0.bz2 - False
</pre>
 
=={{header|REXX}}==
This REXX version handles the extra credit requirement.
<langsyntaxhighlight lang="rexx">/*REXX programpgm displays if a filename has a known extension (as per a list of EXTsextensions). */
$= 'zip rar 7z gz archive A## tar.bz2'; upper $ /*a list of "allowable" file extensions*/
parse arg fn /*obtain optional argument from the CL.*/
@.= /*define the default for the @. array.*/
if fn\='' then @.1 = strip(fn) /*A filename specified? Then use it. */
else do; @.1 = "MyData.a##" /*No " " elseElse use list*/
@.2 = "MyData.tar.Gz"
@.3 = "MyData.gzip"
Line 654 ⟶ 2,255:
@.8 = "MyData_v1.0.bz2"
end
#= words($)
 
do j=1 while @.j\=='' /*traipse through @ list of file exts.*/
do j=1 while @.j\==''; @@= file=@.j; upper file @@ /*gettraipse athrough filename;@ and thenfile uppercaseextension itlist*/
do k=1 for # until right(@@, L)==x /*searchSearch $ list, tois seeextension ifin ext is inlist? it.*/
x= . || word($, k); L=length(x) /*construct filethe extension; getof lengththe file. */
end /*k*/ if right(file, L)==x then leave /*Does [↓] display file, and hasa annay allowableor extension?yea.*/
say right(@.j, 40) ' ' end right( /*word( "false true", 1 + (k*/<=#) ), 5)
end /*j*/ say right(@.j, 30) ' ' word("false true", 1 + (k<=#) ) /*naystick ora yeafork in it, we're all done. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
end /*j*/ /*stick a fork in it, we're all done. */</lang>
{{out|output}}
<pre>
MyData.a## true
MyData.tar.Gz true
MyData.gzip false
MyData.7z.backup false
MyData... false
MyData false
MyData_v1.0.tar.bz2 true
MyData_v1.0.bz2 false
</pre>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : File extension is in extensions list
 
extensions = [".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"]
filenames = ["MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup",
"MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
 
for n = 1 to len(filenames)
flag = 0
for m = 1 to len(extensions)
if right(filenames[n], len(extensions[m])) = extensions[m]
flag = 1
see filenames[n] + " -> " + extensions[m] + " -> " + " true" + nl
exit
ok
next
if flag = 0
see filenames[n] + " -> " + "false" + nl
ok
next
</syntaxhighlight>
Output:
<pre>
MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|Ruby}}==
<syntaxhighlight lang="ruby">def is_ext(filename, extensions)
if filename.respond_to?(:each)
filename.each do |fn|
is_ext(fn, extensions)
end
else
fndc = filename.downcase
extensions.each do |ext|
bool = fndc.end_with?(?. + ext.downcase)
puts "%20s : %s" % [filename, bool] if bool
end
end
end
</syntaxhighlight>
{{out}}
<pre>
is_ext ['MyData.a##', 'MyData.tar.Gz', 'MyData.gzip', 'MyData.7z.backup', 'MyData...', 'MyData', 'MyData.tar.bz2'],
%w(zip rar 7z gz archive A## tar.bz2)
#=>
MyData.a## : true
MyData.tar.Gz : true
MyData.tar.bz2 : true
</pre>
 
=={{updateheader|RubyRust}}==
Does extra credit.
<syntaxhighlight lang="rust">fn main() {
let exts = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"];
let filenames = [
"MyData.a##",
"MyData.tar.Gz",
"MyData.gzip",
"MyData.7z.backup",
"MyData...",
"MyData",
"MyData_v1.0.tar.bz2",
"MyData_v1.0.bz2",
];
 
println!("extenstions: {:?}\n", exts);
<lang ruby>extensions = [".c",".o",""]
 
["foo.C","foo.zkl","foo","foo."].each do |f|
for filename in filenames.iter() {
puts "%5s : %s" % [extensions.include?( File.extname(f).downcase ), f]
let check = exts.iter().any(|ext| {
end</lang>
filename
.to_lowercase()
.ends_with(&format!(".{}", ext.to_lowercase()))
});
println!("{:20} {}", filename, check);
}
}
</syntaxhighlight>
{{out}}
<pre>
extensions: ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]
true : foo.C
 
false : foo.zkl
MyData.a## true
true : foo
MyData.tar.Gz true
true : foo.
MyData.gzip false
MyData.7z.backup false
MyData... false
MyData false
MyData_v1.0.tar.bz2 true
MyData_v1.0.bz2 false
</pre>
 
=={{header|Scala}}==
 
<syntaxhighlight lang="scala"> def isExt(fileName: String, extensions: List[String]): Boolean = {
{{update|Scala}}
extensions.map { _.toLowerCase }.exists { fileName.toLowerCase endsWith "." + _ }
}
</syntaxhighlight>
 
=={{header|Sidef}}==
<lang Scala>def isExt(fileName: String, extensions: List[String]): Boolean = {
{{trans|Perl}}
extensions.map { _.toLowerCase }.exists { fileName.toLowerCase endsWith _ }
<syntaxhighlight lang="ruby">func check_extension(filename, extensions) {
}</lang>
filename ~~ Regex('\.(' + extensions.map { .escape }.join('|') + ')\z', :i)
}</syntaxhighlight>
 
Testing:
<syntaxhighlight lang="ruby">var extensions = ['zip', 'rar', '7z', 'gz', 'archive', 'A##', 'tar.bz2']
 
var files = [
'MyData.a##', 'MyData.tar.Gz', 'MyData.gzip', 'MyData.7z.backup',
'MyData...', 'MyData', 'MyData_v1.0.tar.bz2', 'MyData_v1.0.bz2'
]
 
for file in files {
printf("%-19s - %s\n", file, check_extension(file, extensions))
}</syntaxhighlight>
{{out}}
<pre>
MyData.a## - true
MyData.tar.Gz - true
MyData.gzip - false
MyData.7z.backup - false
MyData... - false
MyData - false
MyData_v1.0.tar.bz2 - true
MyData_v1.0.bz2 - false
</pre>
 
=={{header|Tcl}}==
 
<syntaxhighlight lang="tcl">
{{update|Tcl}}
 
# This example includes the extra credit.
<lang tcl># Note that these are already all in lower case
# With a slight variation, a matching suffix can be identified.
set exts {".txt" ".gz" ".bat" ".c" ".c++" ".exe" ".pdf"}
# Note that suffixes with two or more dots (ie a dot in suffix) are checked for each case.
set filenames {
# This way, filename.1.txt will match for txt, and filename3.tar.gz.1 will match for tar.gz.1 for example.
text.txt
 
text.TXT
# Example input data:
test.tar.gz
set f_list [list \
test/test2.exe
"MyData.a##" \
test\\test2.exe
MyData.tar.Gz \
test
MyData.gzip \
a/b/c\\d/foo
MyData.7z.backup \
foo.c
"MyData..." \
foo.C
MyData \
foo.C++
MyData_v1.0.tar.bz2 \
foo.c#
MyData_v1.0.bz2 ]
foo.zkl
set suffix_input_list [list zip rar 7z gz archive "A##" tar.bz2 ]
document.pdf
 
# Prefix a dot to any suffix that does not begin with a dot.
set suffix_list [list ]
foreach s $suffix_input_list {
if { [string range $s 0 0] ne "." } {
set s2 "."
} else {
set s2 ""
}
append s2 $s
lappend suffix_list [string tolower $s2]
}
 
# Check each filename
foreach name $filenames {
foreach filename0 $f_list {
set ext [file extension $name]
ifset filename1 {[string tolower $ext][file intail $exts} {filename0]]
set suffix1 [file extension $filename1]
puts "'$ext' (of $name) is present"
set file_suffix_list [list $suffix1]
set filename2 [file rootname $filename1]
set i 0
# i is an infinite loop breaker. In case there is some unforseen case..
while { $filename2 ne "" && $filename2 ne $filename1 && $i < 32} {
# Another suffix is possible
set suffix2 [file extension $filename2]
if { $suffix2 ne "" } {
# found another suffix
append suffix2 $suffix1
lappend file_suffix_list $suffix2
}
set suffix1 $suffix2
set filename1 $filename2
set filename2 [file rootname $filename2]
incr i
}
set a_suffix_found_p 0
foreach file_suffix $file_suffix_list {
if { $file_suffix in $suffix_list } {
set a_suffix_found_p 1
}
}
puts -nonewline "${filename0}\t"
if { $a_suffix_found_p } {
puts "true"
} else {
puts "false"
puts "'$ext' (of $name) is absent"
}
}
}</lang>
 
</syntaxhighlight>
{{out}}
<pre>
MyData.a## true
MyData.tar.Gz true
MyData.gzip false
MyData.7z.backup false
MyData... false
MyData false
MyData_v1.0.tar.bz2 true
MyData_v1.0.bz2 false
</pre>
 
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
const (
extensions = [".zip", ".rar", ".7z", ".gz", ".archive", ".a##", ".tar.bz2"]
filenames = ["MyData.a##", "MyData.tar.gz", "MyData.gzip", "MyData.7z.backup",
"MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"]
)
 
fn main() {
outer:
for oidx, file in filenames {
for idx, extension in extensions {
if file.substr_ni(file.len - extension.len, file.len) == extension {
println("${filenames[oidx]} -> ${extensions[idx]} -> true")
continue outer
}
}
println("${filenames[oidx]} -> false")
}
}
</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## -> .a## -> true
MyData.tar.gz -> .gz -> true
MyData.gzip -> false
MyData.7z.backup -> false
MyData... -> false
MyData -> false
MyData_v1.0.tar.bz2 -> .tar.bz2 -> true
MyData_v1.0.bz2 -> false
</pre>
 
=={{header|Wren}}==
{{libheader|Wren-str}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./str" for Str
import "./fmt" for Fmt
 
var exts = ["zip", "rar", "7z", "gz", "archive", "A##", "tar.bz2"]
 
var tests = [
"MyData.a##", "MyData.tar.Gz", "MyData.gzip" , "MyData.7z.backup",
"MyData...", "MyData", "MyData_v1.0.tar.bz2", "MyData_v1.0.bz2"
]
 
var ucExts = exts.map { |e| "." + Str.upper(e) }
for (test in tests) {
var ucTest = Str.upper(test)
var hasExt = false
var i = 0
for (ext in ucExts) {
hasExt = ucTest.endsWith(ext)
if (hasExt) {
Fmt.print("$-20s $s (extension: $s)", test, hasExt, exts[i])
break
}
i = i + 1
}
if (!hasExt) Fmt.print("$-20s $-5s", test, hasExt)
}</syntaxhighlight>
 
{{out}}
<pre>
MyData.a## true (extension: A##)
MyData.tar.Gz true (extension: gz)
MyData.gzip false
MyData.7z.backup false
MyData... false
MyData false
MyData_v1.0.tar.bz2 true (extension: tar.bz2)
MyData_v1.0.bz2 false
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">string 0;
 
func ToUpper(C); \Convert character to upper case
int C;
return if C>=^a & C<=^z then C&$DF else C;
 
func HasExt(File, Ext); \Return 'true' if File has Ext(ension)
char File, Ext;
int I, J;
[I:= 0;
while File(I) # 0 do I:= I+1;
while File(I) # ^. and I > 0 do I:= I-1;
I:= I+1;
J:= 0;
loop [if ToUpper(File(I+J)) # ToUpper(Ext(J)) then return false;
if Ext(J) = 0 then return true;
J:= J+1;
];
];
 
int Exts, Ext, Files, Test;
[Exts:= ["zip", "rar", "7z", "gz", "archive", "A##"];
Files:= ["MyData.a##", "MyData.tar.Gz", "MyData.gzip" , "MyData.7z.backup",
"MyData...", "MyData" ];
for Test:= 0 to 5 do
[for Ext:= 0 to 5 do
[if HasExt(Files(Test), Exts(Ext)) then
[Text(0, " true : ");
Ext:= 100;
];
];
if Ext = 6 then Text(0, "false : ");
Text(0, Files(Test));
CrLf(0);
];
]</syntaxhighlight>
{{out}}
<pre>
true : MyData.a##
'.txt' (of text.txt) is present
true : MyData.tar.Gz
'.TXT' (of text.TXT) is present
false : MyData.gzip
'.gz' (of test.tar.gz) is present
false : MyData.7z.backup
'.exe' (of test/test2.exe) is present
false : MyData...
'.exe' (of test\test2.exe) is present
false : MyData
'' (of test) is absent
'' (of a/b/c\d/foo) is absent
'.c' (of foo.c) is present
'.C' (of foo.C) is present
'.C++' (of foo.C++) is present
'.c#' (of foo.c#) is absent
'.zkl' (of foo.zkl) is absent
'.pdf' (of document.pdf) is present
</pre>
 
=={{header|zkl}}==
<langsyntaxhighlight lang="zkl">fcn hasExtension(fnm){
var [const] extensions=T(".zip",".rar",".7z",".gz",".archive",".a##");
nm,ext:=File.splitFileName(fnm)[-2,*].apply("toLower");
Line 754 ⟶ 2,623:
else False
}
foreach nm in (nms:=T("MyData.a##","MyData.tar.Gz","MyData.gzip","MyData.7z.backup",
"MyData...","MyData",
"MyData_v1.0.tAr.bz2","MyData_v1.0.bz2")){;
foreach nm in (nms){ println("%20s : %s".fmt(nm,hasExtension(nm))); }</syntaxhighlight>
}</lang>
{{out}}
<pre>
2,056

edits