我知道有更简单的方法来get file extensions with JavaScript,但部分是为了练习我的regexp技能,我想尝试使用正则表达式将文件名拆分为两个字符串,在最后一个点(.
字符)之前和之后。
这是我目前掌握的情况
const myRegex = /^((?:[^.]+(?:\.)*)+?)(\w+)?$/
const [filename1, extension1] = 'foo.baz.bing.bong'.match(myRegex);
// filename1 = 'foo.baz.bing.'
// extension1 = 'bong'
const [filename, extension] = 'one.two'.match(myRegex);
// filename2 = 'one.'
// extension2 = 'two'
const [filename, extension] = 'noextension'.match(myRegex);
// filename2 = 'noextension'
// extension2 = ''
我试着用否定前瞻来表示'only match a literal .如果它后面跟着一个以结尾的单词,就像这样,把(?:\.)*
改为(?:\.(?=\w+.))*
:/^((?:[^.]+(?:\.(?=(\w+\.))))*)(\w+)$/gm
但是我想只使用正则表达式排除最后一个句点,并且最好在初始组中匹配'noextension',我怎么能只使用正则表达式呢?
下面是我的regexp临时文件:https://regex101.com/r/RTPRNU/1
4条答案
按热度按时间ig9co6j11#
对于第一个捕获组,可以使用1个或多个单词字符开始匹配。然后,可以选择重复
.
,然后再重复1个或多个单词字符。然后,您可以使用可选的非捕获组匹配
.
,并捕获组2中的1个或多个单词字符。由于第二个非捕获组是可选的,因此第一次重复应该是贪婪的。
模式匹配
^
字符串开头(
捕获组1\w+(?:\.\w+)*?
匹配1个以上单词字符,并可选择重复.
和1个以上单词字符)
关闭组1(?:
要整体匹配的非捕获组\.(\w+)
匹配.
并在捕获组2中捕获1个以上的单词字符)?
关闭非捕获组并使其可选$
字符串结束Regex demo
另一个选项如@Wiktor Stribiżew张贴在评论中,是使用一个非贪婪的点来匹配文件名的任何字符:
Regex demo
5us2dqdw2#
只是想做一个关于这个问题的最新讨论,因为我想将文件名分成“名称”和“扩展名”两部分--并且无法找到任何支持我的所有测试用例的好解决方案......我想支持以“.”开头的文件名,它应该作为“名称”返回,我还想支持没有任何扩展名的文件。
所以我用这行代码来处理我所有的用例
它将给予以下输出
我发现这就是我想要的。
m3eecexj3#
如果你真的想使用正则表达式,我建议使用两个正则表达式:
wkyowqbh4#
不需要四处张望就能说得更清楚更准确的话怎么样...
1.命名组变量...
/^(?<noextension>\w+)$|(?<filename>\w+(?:\.\w+)*)\.(?<extension>\w+)$/
1.没有命名组...
/^(\w+)$|(\w+(?:\.\w+)*)\.(\w+)$/
两个刚刚显示的变体都可以缩短为2个捕获组,而不是上面的变体的3个捕获组,在我看来,这使得正则表达式更容易工作,代价是可读性较差...
1.命名组变量...
/(?<filename>\w+(?:\.\w+)*?)(?:\.(?<extension>\w+))?$/
1.没有命名组...
/(\w+(?:\.\w+)*?)(?:\.(\w+))?$/
第一个