通过CMake剥离文件名(最短)扩展名(获取文件名删除最后一个扩展名)

Pet*_*ter 11 cmake

get_filename_component可用于删除/提取最长的扩展名.

EXT =文件名最长扩展名(.bc来自d/abc)

NAME_WE =没有目录或最长扩展名的文件名

我的名字中有一个带圆点的文件,所以我需要最短的扩展名:

set(MYFILE "a.b.c.d")
get_filename_component(MYFILE_WITHOUT_EXT ${MYFILE} NAME_WE)
message(STATUS "${MYFILE_WITHOUT_EXT}") 
Run Code Online (Sandbox Code Playgroud)

报告

-- a
Run Code Online (Sandbox Code Playgroud)

但我想要

-- a.b.c
Run Code Online (Sandbox Code Playgroud)

在没有最短扩展名的情况下查找文件名的首选方法是什么?

Ant*_*nio 17

我会做:

string(REGEX REPLACE "\\.[^.]*$" "" MYFILE_WITHOUT_EXT ${MYFILE})
Run Code Online (Sandbox Code Playgroud)

正则表达式匹配一个点(\\.,参见下一段),后跟任意数量的字符,[^.]*直到字符串($)的末尾不是一个点,然后用空字符串替换它"".

元字符点(通常在正则表达式中表示"匹配任何字符")需要转义为a \来解释为文字点.但是,在CMake字符串文字(如C字符串文字)中,\是一个特殊字符,也需要进行转义(另请参见此处).因此,您获得了奇怪的序列\\..

请注意,(几乎所有)元字符不需要在字符类中进行转义:因此我们有[^.]和没有[^\\.].

最后,请注意,如果分析的文件名中没有点(在这种情况下输出对应于输入字符串),此表达式也是安全的.

链接到字符串命令文档.


Rei*_*ica 6

我会用一个简单的正则表达式来解决这个问题:

string(REGEX MATCH "^(.*)\\.[^.]*$" dummy ${MYFILE})
set(MYFILE_WITHOUT_EXT ${CMAKE_MATCH_1})
Run Code Online (Sandbox Code Playgroud)


Sam*_*ley 6

CMake 3.14 开始,可以get_filename_component直接使用此方法。

NAME_WLE: 没有目录或最后一个扩展名的文件名

set(INPUT_FILE a.b.c.d)
get_filename_component(OUTPUT_FILE_WE ${INPUT_FILE} NAME_WE)
get_filename_component(OUTPUT_FILE_WLE ${INPUT_FILE} NAME_WLE)
Run Code Online (Sandbox Code Playgroud)

OUTPUT_FILE_WE将被设置为a,并且OUTPUT_FILE_WLE将被设置为a.b.c