为何正则表达式'.*[.].*$'能匹配带扩展名的文件名?
拆解正则表达式
.*[.].*$ 的匹配逻辑 嘿,我来帮你一步步捋清楚这个正则是怎么匹配foo.bar这类带扩展名的文件名的,拆成几个部分看就很简单了:
.*:先看这部分,正则里的.是匹配任意单个字符(除了换行),*是让前面的字符重复0次或多次。这部分的作用是匹配从字符串开头到某个点号之前的内容——不过要注意*是「贪婪模式」,它会尽可能多“吃”字符,但后面等着要匹配真实的点号,所以它会停在最后一个点号的前面(如果字符串里有多个点的话)。[.]:这个是关键!正则里.是特殊字符,直接写的话会匹配任意字符,但用方括号把它括起来[.],就表示匹配字面意义的点号,也就是文件名里的那个分隔点。.*$:最后这部分,.还是匹配任意字符,*重复0次或多次,$表示字符串的结尾。所以这部分负责匹配点号之后到文件名结束的所有内容,也就是咱们说的扩展名。
咱们拿foo.bar走一遍完整匹配流程:
.*从开头的f开始匹配,一路吃到foo就停了——因为再往后的.要留给[.]来匹配,不能抢;[.]精准匹配foo后面的那个点号;.*$接着匹配点号后面的bar,一直到字符串结尾$,完美覆盖整个文件名。
再拿my_files.txt试一遍:.*匹配my_files,[.]匹配中间的点,.*$匹配txt,整个字符串就被成功匹配啦。
不过这里要提个小bug:这个正则其实会匹配一些不太规范的文件名,比如file..txt(两个点)、file.(点在结尾)甚至.hidden(点在开头),因为.*允许匹配0个字符。如果要严格匹配「前面至少有一个字符,点后也至少有一个字符」的标准文件名,把*换成+就行,也就是.+[.].+$(+表示匹配1次或多次)。
最后补个小知识点:如果字符串是foo.bar.baz这种多个点的,这个正则会匹配整个字符串——因为.*是贪婪的,它会吃到最后一个点的前面,然后匹配最后那个点和后面的内容。如果想匹配第一个点之前的部分,就得用非贪婪模式.*?[.],不过这就是额外的内容啦~
内容的提问来源于stack exchange,提问作者Jun
相关产品推荐
相关产品推荐

