在工作中我遇到了一个问题,需要解析没有一致模式的文件名。 我尝试了相当多的时间来实现纯正则表达式解决方案,但最终决定在代码中进行一些分割,并将正则表达式应用于分割部分。 效果很好,但我想重新审视这一点并从中学习,如果有一种有效的方法可以在正则表达式中完成这一切,这样我就可以学习。
如果后面有一个
[\w\.\-]+
,我无法弄清楚如何不匹配v?\d+\.\d+
。我研究过前瞻/后瞻,但无法真正理解如何将其中任何一个应用于这种情况。
我的“最接近”尝试: regex101 链接包含有关匹配和错误的更多详细信息。
https://regex101.com/r/nz4Bxl/1
(?P<name>([\w\-]+)+\.?)(?P<version>(\.?\d+\.?)+\.?)(\.[a-z]{3,})/gm
使用此模式,大多数字符串都会匹配(尽管大多数版本缺少前导数字和句点),但以下情况除外: appname.v1.2.3.exe(没有名称匹配,版本缺少 1。) appname.v1.02.03.exe(没有名称匹配,版本缺少 1。)
https://regex101.com/r/FyG7Mm/1/
(?P<name>([\w\-]+)]?)(?P<version>((\d+\.){1,}\d+\.?))\.[a-z]{3,}/gm
使用此模式,大多数输入字符串都被匹配,除了:app-name.1.2.3.exe(没有匹配)appname.v1.2.3.exe(版本匹配,但没有名称匹配)appname.v1.02.03 .exe(版本匹配,但名称不匹配)appname71name.1.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
我问了https://chatgpt.com/并在20秒内得到了答案,并附有解释。我们生活在一个可怕的时代。但提醒一下,这种琐碎的任务正是人工智能所擅长的!
^(?<name>[a-zA-Z0-9_-]+(?:[a-zA-Z0-9_-]*)?)(?:\.|_|\-)(?<version>(?:v)?\d+\.\d+\.\d+)\.exe$
解释:
^ 断言字符串的开头。
(?[a-zA-Z0-9_-]+(?:[a-zA-Z0-9_-]*)?) 捕获名称部分:
[a-zA-Z0-9_-]+ 匹配一个或多个字母数字字符、下划线或连字符。
(?:[a-zA-Z0-9_-]*)?可选择匹配更多字母数字字符、下划线或连字符。
(?:.|_|-) 匹配点、下划线或连字符作为名称和版本之间的分隔符。
(?(?:v)?\d+.\d+.\d+) 捕获版本部分:
(?:v)?可选地匹配开头的“v”。
\d+.\d+.\d+ 匹配版本格式(major.minor.patch)。
.exe$ 确保字符串以 .exe 结尾。
尝试匹配:
^(?<name>(?:[^_.-]|-(?!v?\d))+)[._v-]+(?P<version>\d+(?:\.\d+)+)\.exe$
并替换为:
name: ${name} version: ${version}
参见:regex101
说明
比赛:
^
:字符串的开头(?<name>...)
:捕获组“名称”
(?:...)+
:重复匹配
[^_.-]
:非下划线、点或减号|
:或-(?!v?\d)
:减号前面不能有数字或文字“v”和数字[._v-]+
:匹配点、下划线、v 或减号(?P<version>)
:后面是版本号
\d+
:由数字组成(?:\.\d+)+
:后面反复跟一个点,后面跟数字\.exe$
:在文件扩展名“.exe”之前更换:
name: ${name} version: ${version}
:替换为捕获组名称和版本