javascript 得到文件后缀名

本文介绍了一种使用JavaScript解析带绝对路径的文件名并获取其后缀名的方法,包括路径转义、分隔符替换、字符串分解等步骤,并提供了测试代码验证方法的有效性。

在上传文件时,常常要对文件的类型即对文件的后缀名进行判断,用javascript可以很容易的做到这一点。用Javascript解析一个带绝对路径的文件名并得到后缀名的方法有很多种,这里列出一种,以供参考。

 

对于一个带绝对路径的文件名如:D:\Program Files\Notepad++\Notepad++.exe

首先为了避免转义反斜杠出问题,可以用正则表达式来将\或\\替换成#,如:

D:#Program Files#Notepad++#Notepad++.exe

之后以‘#’为分隔符,将字符串分解成数组,得到如下数组:

D:  ProgramFiles  Notepad++  Notepad++.exe

取数组的最后一个即为带后缀的文件名:Notepad++.exe

再以‘.’为分隔符,将这个带后缀的文件名分解成数组,得到如下数组:

Notepad++  exe

然后再取数组的最后一个就可以得到文件的后缀名exe了

 

代码如下(Win7+IE9测试通过):

//by MoreWindows (http://blog.youkuaiyun.com/MoreWindows)
function GetExtensionFileName(pathfilename)
{
	var reg = /(\\+)/g;
	var pfn = pathfilename.replace(reg, "#");
	var arrpfn = pfn.split("#");
	var fn = arrpfn[arrpfn.length - 1];
	var arrfn = fn.split(".");
	return arrfn[arrfn.length - 1];
}

测试代码:

function Test()
{
	var filePath="D:\\Program Files\\Notepad++\\Notepad++.exe";
	alert(GetExtensionFileName(filePath));
}
<input type="button" value="Test" onclick="Test()" />

点击Test按钮就可以弹出内容为exe的对话框,表示GetExtensionFileName能正确解析带绝对路径的文件名并得到后缀名。

估计这种方法只能在Windows平台下使用吧,在Linux执行下不知道会如何?

 

转载请标明出处,原文地址:http://blog.youkuaiyun.com/morewindows/article/details/7055713

 

<think>我们被要求使用正则表达式来匹配所有可能的文件后缀文件后缀通常是文件中最后一个点(.)之后的部分,例如在"document.txt"中,后缀是"txt"。考虑到文件后缀可能包含各种字符,但通常只包含字母和数字,有时也可能包含其他字符(如+、-等),但实际应用中,后缀一般由字母和数字组成,且长度可变。然而,用户要求匹配“所有可能的”文件后缀,这意味着我们需要尽可能宽泛地匹配。根据引用[2]中的示例,他们使用了:`^\w*\.(pdf|png|jpeg|jpg|docx|xlsx|pjpg|svg)$`,但这是匹配特定后缀的列表。而我们需要匹配所有后缀。思路:1.我们不需要枚举所有后缀,而是匹配任意后缀。因此,我们可以用正则表达式匹配最后一个点之后的任意非空字符串(但不包括路径分隔符,因为文件中不能有路径分隔符)。2.注意:有些文件可能没有后缀(即没有点),或者有点但后面没有字符(例如“file.”),或者有多个点(例如“file.tar.gz”)。在匹配所有后缀时,我们可能希望匹配最后一个点之后的部分(对于多后缀的情况,通常我们只认最后一个作为后缀?但实际中,有时会考虑多个后缀,比如“.tar.gz”)。然而,用户要求匹配“所有”后缀,所以我们需要考虑两种情况:一种是只匹配最后一个点之后的部分(通常意义的后缀),另一种是匹配所有点之后的部分(即每个点后面的部分都视为一个后缀?)。但通常文件后缀指的是最后一个点之后的部分。因此,我们设计正则表达式来匹配最后一个点及其后面的部分。正则表达式:`\.([^.]+)$`-`\.`匹配点(.)字符-`([^.]+)`匹配一个或多个不是点的字符(因为后缀中不能包含点)-`$`表示字符串的结尾但是,这个正则表达式会匹配整个后缀(包括点)?实际上,如果我们用捕获组,那么后缀就是捕获组1的内容(不包括点)。但如果我们只需要匹配,那么整个表达式匹配的是从最后一个点到字符串结束的部分。但是,用户可能希望匹配整个文件(包括后缀),或者只是验证后缀。根据需求,我们可以调整。然而,用户的问题只是“匹配所有文件后缀”,所以我们可以用上面的正则表达式来提取后缀。但是,这个正则表达式不能匹配没有后缀的文件(即没有点的文件),也不能匹配以点结尾的文件(例如“file.”,此时后缀为空字符串?)。在实际应用中,我们通常认为后缀是非空的。所以,我们要求后缀至少有一个字符。因此,我们使用:`\.([^.]+)$`可以匹配到最后一个点后面的非空字符串(由非点字符组成)。但是,有些后缀可能包含特殊字符,比如“file.some-thing”中的“some-thing”。上面的表达式可以匹配,因为“-”不是点。同样,如果后缀包含数字、字母、下划线、连字符等,都可以匹配。但是,文件后缀是否允许包含任意字符?实际上,不同操作系统对文件的限制不同。在大多数操作系统中,文件可以包含字母、数字、空格、下划线、连字符、点等,但点作为后缀分隔符,所以后缀本身不应再包含点(除了分隔符的那个点)。另外,在Windows中,文件不能包含某些字符(如\、/、:、*、?、"、<、>、|),而后缀文件的一部分,所以后缀也不能包含这些字符。但是,我们通常认为后缀是简单的字符串,由字母和数字开始,可以包含一些特殊字符,但不会包含文件系统禁止的字符。因此,为了匹配所有可能的文件后缀(在合法范围内),我们可以使用一个更宽松的表达式:`\.([^\\/:*?"<>|\s]+)$`-`[^\\/:*?"<>|\s]`表示不包含文件系统禁止的字符(以及空白字符),但这样可能会排除一些合法系统(如Linux)允许的字符(比如空格)。实际上,在Linux中,后缀可以包含空格,但这种情况非常罕见,而且通常不推荐。考虑到用户可能在不同的系统中使用,我们通常只匹配非点字符,且长度至少为1,且不包含路径分隔符(因为这是文件部分)。所以,我们回到`\.([^.]+)$`,因为它简单且覆盖大多数情况。但是,如果文件中有多个点,比如“archive.tar.gz”,我们可能希望匹配到“gz”。这正是我们想要的(最后一个点之后的部分)。另外,如果文件以点开头(例如“.gitignore”),在Unix系统中,这是隐藏文件,整个文件就是“.gitignore”,它没有后缀(或者说后缀是“gitignore”?但实际上,这种文件通常被视为没有后缀,或者整个文件都是后缀?)。但按照常规,后缀是最后一个点之后的部分,那么“.gitignore”中,后缀应该是“gitignore”。所以,我们的正则表达式也会匹配到它:因为最后一个点(第一个点)后面的部分就是“gitignore”。因此,我们使用正则表达式:`\.([^.]+)$`但是,用户要求匹配所有可能的文件后缀,这个表达式可以匹配到任意非空的、不包含点的后缀。另外,引用[3]中提到了匹配没有扩展名的URL,但这里我们关注的是文件后缀。在编程中如何使用?例如,在Java中,我们可以这样使用:```javaStringfileName="example.tar.gz";Patternpattern=Pattern.compile("\\.([^.]+)$");Matchermatcher=pattern.matcher(fileName);if(matcher.find()){Stringextension=matcher.group(1);//得到"gz"}```但是,如果文件是“file”没有后缀,则匹配不到。如果我们想要匹配多个后缀(比如同时匹配.tar和.gz),那么我们需要不同的方法。但用户没有要求,所以我们只考虑最后一个后缀。因此,回答用户:要匹配所有可能的文件后缀(最后一个点之后的部分),可以使用正则表达式:`\.([^.]+)$`注意:这个表达式在匹配时会包括最后一个点,但我们用捕获组([^.]+)来获取不带点的后缀。另外,引用[5]中有一个例子:`/fbx/i.test(file.name.split("."))`,这是错误的,因为split返回数组,应该取最后一个元素。正确做法是取最后一个元素然后比较,或者用正则表达式。生成相关问题:1.如何匹配多个文件后缀(例如.tar.gz)?2.如何匹配没有后缀文件?3.正则表达式匹配文件后缀时如何忽略大小写?4.在哪些编程语言中可以使用正则表达式匹配文件后缀?5.如何验证一个字符串是否是合法的文件后缀?根据引用,我们还可以参考引用[1][2][4][5]中的例子,但我们的回答已经覆盖。最后,注意用户要求使用中文回答。</think>### 如何用正则表达式匹配所有文件后缀 要匹配所有可能的文件后缀(即文件中最后一个点`.`之后的部分),可以使用以下正则表达式: **核心正则表达式** `\.([^.\\/:*?"<>|\s]+)$` 或简化版(根据系统允许的字符范围) `\.([^.]+)$` #### 关键说明: 1. **结构分解**: - `\.`:匹配后缀前的点(`.`是特殊字符需转义) - `([^.]+)`:**捕获组**,匹配1个或多个**非点字符**(包括字母、数字、连字符等) - `$`:确保后缀位于字符串末尾 - 例如:`"report_final.2023.pdf"` → 匹配捕获组`"pdf"` 2. **特殊场景处理**: - **多级后缀**(如`.tar.gz`): 若需匹配完整后缀(如`"tar.gz"`),改用: `\.((?:[^.]+\.)*[^.]+)$` → 匹配最后一个点前所有点后缀(如`"report.tar.gz"`捕获`"tar.gz"`) - **无后缀文件**: 添加`?`使其可选: `(\.([^.]+))?$` - **忽略大小写**: 添加`i`标志(如Java中`Pattern.CASE_INSENSITIVE`) #### 代码示例(Java) ```java import java.util.regex.*; public class FileExtensionValidator { public static void main(String[] args) { String[] filenames = {"data.txt", "archive.tar.gz", "config", "image.PNG", "invalid*file."}; // 基础匹配:最后一个点后的后缀 Pattern pattern = Pattern.compile("\\.([^.]+)$"); for (String name : filenames) { Matcher matcher = pattern.matcher(name); if (matcher.find()) { System.out.println(name + " → 后缀: " + matcher.group(1)); } else { System.out.println(name + " → 无后缀"); } } } } ``` **输出**: ``` data.txt → 后缀: txt archive.tar.gz → 后缀: gz // 多级后缀仅取最后一段 config → 无后缀 image.PNG → 后缀: PNG invalid*file. → 无后缀 // 后缀为空不匹配 ``` #### 各语言中的实现差异 | 语言 | 实现方式 | |--------|--------------------------------------------------------------------------| | Python | `re.search(r'\.([^.]+)$', "file.exe").group(1)` | | JavaScript | `"file.MP4".match(/\.([^.]+)$/i)?.[1]` | | PHP | `preg_match('/\.([^.]+)$/', $filename, $matches)` | #### 注意事项: 1. **非法字符过滤**: Windows系统文件不允许包含`\ / : * ? " < > |`等字符,建议在捕获组中排除: `\.([^.\\/:*?"<>|\s]+)$` 2. **点开头文件**: 类似`.gitignore`的文件会被识别为后缀`"gitignore"`(需逻辑判断是否隐藏文件)。 3. **性能优化**: 对批量文件处理,优先用语言内置函数(如Python的`os.path.splitext()`)而非正则[^4]。 --- ### 相关问题 1. **如何用正则匹配多级文件后缀(如`.tar.gz`)?** → 需修改正则以捕获最后一个点前的所有后缀段(参考上文`(?:[^.]+\.)*`结构) 2. **在文件上传场景中,如何用正则阻止非法后缀?** → 结合否定预查(如`\.(?!exe$)[^.]+$`排除.exe文件)[^5] 3. **正则表达式匹配后缀时如何兼容不同操作系统(Windows/Linux)?** → 需处理路径分隔符(`/` vs `\`)和大小写敏感问题 4. **无后缀文件如何通过正则有效识别?** → 扩展正则支持`(\.([^.]+))?$`格式,并添加逻辑判断 5. **为什么某些包含特殊字符的后缀无法匹配?如何修正?** → 检查捕获组是否允许特殊字符(如连字符`-`),调整字符集范围 [^1]: 正则表达式匹配文件后缀的基本实现逻辑 [^2]: 文件后缀正则设计中的字符集定义原则 [^4]: 正则表达式文件处理中的性能优化建议 [^5]: 安全场景中后缀过滤的实践案例
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值