如何修改路径校验正则表达式,使其仅匹配包含带扩展名文件的路径
提问内容
我当前使用的正则表达式如下:
^(?:(?:[a-z]:|\\[a-z0-9_.$●-]+\[a-z0-9_.$●-]+)\|\?[^\/:*?"<>|\n]+\?)*(?:[^\/:*?"<>|\n]+\)*[^\/:*?"<>|\n]*$
该正则基于O'Reilly的相关实现优化,我已经修正了原表达式中部分未转义的字符,拆分说明如下:
(?:(?:[a-z]:|\\[a-z0-9_.$●-]+\[a-z0-9_.$●-]+)\| # 驱动器部分 \?[^\/:*?"<>|\n]+\?) # 相对路径部分 (?:[^\/:*?"<>|\n]+\)* # 文件夹部分 [^\/:*?"<>|\n]* # 文件部分
我需要在PowerShell中使用该正则,匹配规则为不区分大小写。现在需要对正则做修改,使其仅匹配包含带扩展名文件的路径,不需要适配无扩展名文件的边缘场景。
期望匹配效果:
C:\Applications\Dev\File.txt匹配成功C:\Applications\Dev\匹配失败\\192.168.0.1\SHARE\my folder\test.exe匹配成功..\..\bin\my_executable.exe匹配成功
补充:我参考大家的建议后输出的最终实现已经整理为PowerShell脚本,各位PowerShell爱好者可参考使用。
解决方案
修改后完整正则
(?i)^(?:(?:[a-z]:|\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\?[^\/:*?"<>|\n]+\\?)*(?:[^\/:*?"<>|\n]+\\)*[^\/:*?"<>|\n.]+\.[^\/:*?"<>|\n]+$
核心修改逻辑
原正则末尾的[^\/:*?"<>|\n]*可以匹配任意合法文件名(包括无扩展名的文件、空值),我们将其替换为[^\/:*?"<>|\n.]+\.[^\/:*?"<>|\n]+,强制要求路径末尾的文件名满足以下规则:
- 开头至少有1个非点、非非法字符的合法文件名字符
- 包含1个英文格式的点号
- 点号后至少有1个合法的扩展名字符
这样就自动排除了末尾带反斜杠的纯文件夹路径、无扩展名的文件路径,完全符合需求。
PowerShell使用示例
# 定义正则规则,(?i)显式声明不区分大小写 $pathMatchPattern = '(?i)^(?:(?:[a-z]:|\\[a-z0-9_.$●-]+\\[a-z0-9_.$●-]+)\\|\?[^\/:*?"<>|\n]+\\?)*(?:[^\/:*?"<>|\n]+\\)*[^\/:*?"<>|\n.]+\.[^\/:*?"<>|\n]+$' # 测试用例 @( "C:\Applications\Dev\File.txt", "C:\Applications\Dev\", "\\192.168.0.1\SHARE\my folder\test.exe", "..\..\bin\my_executable.exe" ) | ForEach-Object { [PSCustomObject]@{ 路径 = $_ 匹配结果 = $_ -match $pathMatchPattern } }
测试输出结果
| 路径 | 匹配结果 |
|---|---|
| C:\Applications\Dev\File.txt | True |
| C:\Applications\Dev\ | False |
| \192.168.0.1\SHARE\my folder\test.exe | True |
| ....\bin\my_executable.exe | True |
内容的提问来源于stack exchange,提问作者fmotion1
相关产品推荐
相关产品推荐

