请求帮助生成匹配文件名的正则表达式以解析名称与版本
解析无统一格式文件名的正则方案探索
工作中需要解析格式不统一的文件名,我曾花大量时间尝试纯正则表达式解决,最后用代码分割字符串再对各部分应用正则的方案搞定了,但还是想研究下有没有纯正则的实现方式。
我卡壳的点在于:当字符串后续紧跟v?\d+\.\d+格式的版本号时,如何让[\w\.\-]+不把这部分版本号包含到文件名里。虽然知道前瞻、后顾断言,但不知道怎么在这个场景用。
下面是我之前最接近目标的两次尝试:
尝试1
正则表达式:
(?P<name>([\w\-]+)+\.?)(?P<version>(\.?\d+\.?)+\.?)(\.[a-z]{3,})
问题:能匹配多数字符串,但版本号常缺失开头的数字和句点,而且匹配不了appname.v1.2.3.exe(无名称匹配,版本缺失1.)、appname.v1.02.03.exe(同样无名称匹配,版本缺失1.)这类情况。
尝试2
正则表达式:
(?P<name>([\w\-]+)]?)(?P<version>((\d+\.){1,}\d+\.?))\.[a-z]{3,}
问题:能匹配多数输入,但匹配不了app-name.1.2.3.exe(完全无匹配)、appname.v1.2.3.exe(能匹配到版本,但匹配不到名称)这类情况。
测试用例与期望结果
input ---> desired result app-name.1.2.3.exe ---> name: app-name version: 1.2.3 appname.v1.2.3.exe ---> name: appname version: 1.2.3 appname.v1.02.03.exe ---> name: appname version: 1.02.03 appname71name.1.2.3.exe ---> name: appname71name version: 1.2.3 appname71.1.2.3.exe ---> name: appname71 version: 1.2.3 appname-1.2.3.exe ---> name: appname version: 1.2.3 appname-v1.2.3.exe ---> name: appname version: 1.2.3 appname-v1.02.03.exe ---> name: appname version: 1.02.03 appname71name-1.2.3.exe ---> name: appname71name version: 1.2.3 appname71-1.2.3.exe ---> name: appname71 version: 1.2.3 appname_1.2.3.exe ---> name: appname version: 1.2.3 appname_v1.2.3.exe ---> name: appname version: 1.2.3 appname_v1.02.03.exe ---> name: appname version: 1.02.03 appname71name_1.2.3.exe ---> name: appname71name version: 1.2.3 appname71_1.2.3.exe ---> name: appname71 version: 1.2.3
纯正则解决方案
可以利用非贪婪匹配结合版本号的特征模式来实现,正则表达式如下:
^(?P<name>.*?)(?:[._-]v?(?P<version>\d+(?:\.\d+)+))\.[a-z]{3,}$
正则说明
^:匹配字符串起始位置,确保从开头开始匹配(?P<name>.*?):非贪婪捕获文件名部分,直到后面出现版本号的分隔符+版本模式才停止,避免过度匹配(?:[._-]v?(?P<version>\d+(?:\.\d+)+)):非捕获组匹配版本号的前置分隔符(.、_、-三选一),可选的v前缀,然后捕获版本号(数字开头,后续跟一个或多个数字.结构)\.[a-z]{3,}$:匹配文件后缀(3个及以上小写字母),并定位到字符串结尾,确保匹配完整文件名
这个正则可以覆盖所有测试用例,准确分离文件名和版本号。
内容的提问来源于stack exchange,提问作者Jason Costello
相关产品推荐
相关产品推荐

