https://cmake.org/cmake/help/latest/command/string.html
任何一种语言,操作字符串是最基础的,特别是cmake它的所只支持一种数据类型 --- 字符串。
Search and Replace
纯字符串查找和替换
查找
string(FIND <string> <substring> <output_variable> [REVERSE])
- 从给字的string中查找子串substring返回子串在string中的位置
- 如果提供了REVERSE标记,则从string的末尾开始查找
- 如果没有找到则返回 -1
从上面的的描述中,不难得返回的是第一次匹配的位置:
string(FIND /abb/cc/dd/efg/cc/ddb cc res)
message(${res}) # 5
string(FIND /abb/cc/dd/efg/cc/ddb cc res REVERSE)
message(${res}) # 15
set(MY_STR /abb/cc/dd/efg/cc/ddb)
string(FIND MY_STR cc res REVERSE)
message(${res}) # -1
set(MY_STR /abb/cc/dd/efg/cc/ddb)
string(FIND ${MY_STR} cc res REVERSE)
message(${res}) # 15
替换
string(REPLACE <match_string>
<replace_string> <output_variable>
<input> [<input>...])
先看最基本的用法--只有一个input
set(MY_STR /abb/cc/dd/efg/cc/ddb)
string(REPLACE cc xx RESULT ${MY_STR})
message(${RESULT}) # /abb/xx/dd/efg/xx/ddb
从输出结果可看出,是全局替换!!
多个input是什么情况??
set(MY_STR /abb/cc/dd/efg/cc/ddb)
string(REPLACE cc xx RESULT ${MY_STR} --other/cc/bb/ff/dd)
message(${RESULT}) # /abb/xx/dd/efg/xx/ddb--other/xx/bb/ff/dd
如果有多个input,output是所有input替换后再拼接起来...
如果RESULT有初始值,替换结果只是追加到初始值之后,并不会覆盖原来的值!
使用正则查找和替换
先看看如何指定正则
^ | 配置输入的开始 |
$ | 配置输入的结束 |
. | 任何单个字符 |
\<char> | 如\a 匹配字符'a' |
[] | 匹配括号内的字符 |
[^] | not[] |
- | [a-z]表示[a到z],[+*/-]放在最后就是代表'-' |
* | 匹配前面的模式 0 或 多次 |
? | 匹配前面的模式 0 或 1次 |
+ | 匹配前面的模式 1 或 多次 |
| | pattern1|pattern2匹配pattern1或pattern2 |
() | 分组,在正则替换中,可以引用被匹配的分组 |
注意:没有 {n}或{n,m}的操作符!!
关于优先级
*+和?(和次数相关的)的优先级高于串连操作(比如abce表a串连b串连c...), | 低于串连操作,这就意味着:
1) ab+cb匹配abbcb但不匹配ababcb(先运算ab,然后才是+)
2) ab|cd匹配ab 或 cd 但不匹配 abc或abd
关于转义
- [\t\r\n] 匹配空白符
- [/\\] 匹配 ‘/\’
- \\(\\a\\+b\\) --> \\ - \ 所以它表示的是 \(\a\+b\),
可以使用括号参数 [[ \(\a\+b\)]]
查找
string(REGEX MATCH|MATCHALL <regular_expression>
<output_variable> <input> [<input>...])
从input中把与regular_expression匹配的结果追加到output_variable
string(REGEX MATCH [[.*\.txt]] RESULT a.txt -b.txt c.avi d.jpg)
message(${RESULT}) # a.txt-b.txt
为了输出好看一点,我故意在b.txt之前加了-
MATCHALL:
string(REGEX MATCHALL [[\.txt]] RESULT "a.txt split -b.txt")
message(${RESULT}) #.txt.txt
string(REGEX MATCH [[\.txt]] RESULT "a.txt split -b.txt")
message(${RESULT}) #.txt
替换
string(REGEX REPLACE <regular_expression>
<replacement_expression> <output_variable>
<input> [<input>...])
可以通过 \1, \2 ... \9 引用之前匹配到的分组,在cmake通过\\来获得一个\如:\\1
string(REGEX REPLACE [[(.*)(\.txt|\.png)]] \\1.jpg RESULT a.txt -b.png -c.jpg)
message(${RESULT})# a.txt-b.jpg-c.jpg
在内部好像是先把所有的input合并再执行替换操作,也没有非贪婪模式...
Manipulation
string(APPEND <string_variable> [<input>...])
string(PREPEND <string_variable> [<input>...])
string(APPEND RESULT a)
string(PREPEND RESULT pre-)
string(APPEND RESULT .txt)
message(${RESULT}) # pre-a.txt
string_variable在原来的基础上,前插或向后追加...
string(CONCAT <output_variable> [<input>...])
string(APPEND RESULT a)
string(PREPEND RESULT pre-)
string(APPEND RESULT .txt)
string(CONCAT RESULT text .txt)
message(${RESULT}) # text.txt
RESULT被覆盖了...
string(JOIN <glue> <output_variable> [<input>...])
string(APPEND RESULT a)
string(PREPEND RESULT pre-)
string(APPEND RESULT .txt)
string(CONCAT RESULT text .txt)
string(JOIN - RESULT BB CC DD)
message(${RESULT}) # BB-CC-DD
glue有类似于分隔符的作用...
string(TOLOWER <string> <output_variable>)
string(TOUPPER <string> <output_variable>)
string(LENGTH <string> <output_variable>)
string(SUBSTRING <string> <begin> <length> <output_variable>)
string(STRIP <string> <output_variable>)# 去除两端空白
string(REPEAT <string> <count> <output_variable>) # string 重复 count次
Comparison
string(COMPARE LESS <string1> <string2> <output_variable>)
string(COMPARE GREATER <string1> <string2> <output_variable>)
string(COMPARE EQUAL <string1> <string2> <output_variable>)
string(COMPARE NOTEQUAL <string1> <string2> <output_variable>)
string(COMPARE LESS_EQUAL <string1> <string2> <output_variable>)
string(COMPARE GREATER_EQUAL <string1> <string2> <output_variable>)
比较,将结果(true/false)保存到output_variable中
Hashing
string(<HASH> <output_variable> <input>)
根据字符串计算hash值,不知道是干什么用的,我是没用过的...
https://cmake.org/cmake/help/latest/command/string.html#hashing
Generation
string(ASCII <number> [<number> ...] <output_variable>)
string(ASCII 65 66 RESULT)
message(${RESULT}) # 6566 --> 把数字转成对应的ASCII码
string(HEX <string> <output_variable>) # 要求在3.18以上
我现在用的是3.16,所以这个函数并没有试过.
string(CONFIGURE <string> <output_variable>
[@ONLY] [ESCAPE_QUOTES])
和 configure_file()一样,没用过,略过吧...
随机字符串
string(MAKE_C_IDENTIFIER <string> <output_variable>)
string(MAKE_C_IDENTIFIER ABCD+C67&F RESULT)
message(${RESULT}) # ABCD_C67_F, 非数字或字母的都转成_
string(RANDOM [LENGTH <length>] [ALPHABET <alphabet>]
[RANDOM_SEED <seed>] <output_variable>)
string(RANDOM LENGTH 10 RESULT)
message(${RESULT}) # ou5wr ->产生随机的字符串
LENGTH 默认是 5
生成时间戳
string(TIMESTAMP <output_variable> [<format_string>] [UTC])
%%
New in version 3.8.
A literal percent sign (%).
%d
The day of the current month (01-31).
%H
The hour on a 24-hour clock (00-23).
%I
The hour on a 12-hour clock (01-12).
%j
The day of the current year (001-366).
%m
The month of the current year (01-12).
%b
New in version 3.7.
Abbreviated month name (e.g. Oct).
%B
New in version 3.10.
Full month name (e.g. October).
%M
The minute of the current hour (00-59).
%s
New in version 3.6.
Seconds since midnight (UTC) 1-Jan-1970 (UNIX time).
%S
The second of the current minute. 60 represents a leap second. (00-60)
%f
The microsecond of the current second (000000-999999).
%U
The week number of the current year (00-53).
%V
New in version 3.22.
The ISO 8601 week number of the current year (01-53).
%w
The day of the current week. 0 is Sunday. (0-6)
%a
New in version 3.7.
Abbreviated weekday name (e.g. Fri).
%A
New in version 3.10.
Full weekday name (e.g. Friday).
%y
The last two digits of the current year (00-99).
%Y
The current year.
string(TIMESTAMP RESULT %Y-%m-%d)
message(${RESULT})
JSON
查询字json字符串,不知道在什么地方有用,或许是可以从配置文件中读取到json格式的配置再查询吧...
https://cmake.org/cmake/help/latest/command/string.html#json