【CMake】CMake从入门到实战系列(九)——CMake中的字符串处理指令和运算符

文章目录

      • 一、字符串处理指令string
        • 基本语法
        • 参数含义
      • 二、字符串运算符
        • 字符串比较
        • 字符串连接
        • 字符串替换
        • 字符串长度
        • 字符串截取
        • 字符串转换大小写
        • 字符串正则表达式匹配和替换
        • 字符串查找子字符串
        • 字符串中查找正则表达式匹配的内容
        • 字符串附加
      • 三 、示例

一、字符串处理指令string

在CMake中,string 指令提供了一系列的操作来处理字符串。这些操作包括但不限于比较、替换、连接、长度计算等等。

基本语法

string 指令的基本语法如下:

string(<command> ...)
参数含义

<command> : 是您希望执行的操作类型,比如 LENGTH,APPEND,REPLACE 等。
      LENGTH:计算字符串的长度。
      APPEND:将一个字符串附加到另一个字符串后面。
      REPLACE:替换字符串中的一部分内容。
      SUBSTRING:提取字符串的子字符串。
      COMPARE:比较两个字符串大小,是否相等。
      TOUPPER/TOLOWER:将字符串转换为大写/小写。
      REGEX REPLACE:字符串查找和替换,使用正则表达式匹配和替换字符串的某些部分。
      CONCAT:字符串连接。
      FIND:用于在字符串中查找一个子字符串位置。
      REGEX MATCH:用于在字符串中查找正则表达式匹配的内容。

: 后面的形参根据不同的指令各有差异,下面我们会根据command类型一一示例进行介绍。

二、字符串运算符

下面我们根据command类型一一示例进行介绍:

字符串比较

字符串比较有两种方法。
一种方法是通过条件语句使用 STREQUALSTRLESSSTRGREATER 来比较字符串。

STREQUAL:字符串相等比较。如果相等,则表达式结果为 TRUE,否则为 FALSE。
STRLESS:用于判断一个字符串是否在字典排序上小于另一个字符串。如果是,则表达式结果为 TRUE,否则为 FALSE。
STRGREATER:用于判断一个字符串是否在字典排序上大于另一个字符串。如果是,则表达式结果为 TRUE,否则为 FALSE。

set(var1 "Hello")
set(var2 "World")if("${var1}" STRLESS "${var2}")message(STATUS "var1 is less than var2.")
else()message(STATUS "var1 is not less than var2.")
endif()if("${var1}" STRGREATER "${var2}")message(STATUS "var1 is greater than var2.")
else()message(STATUS "var1 is not greater than var2")
endif()if("${var1}" STREQUAL "${var2}")message(STATUS "var1 is equal to var2.")
else()message(STATUS "var1 is not equal to var2.")
endif()

另一种比较字符串的方法是string(COMPARE <op> <string1> <string2> <output variable>)

这里的<op>是比较操作符,<op>EQUALLESSGREATER,比较结果的返回值同上面STREQUALSTRLESSSTRGREATER<string1><string2>是要比较的字符串,而<output variable>是用来存储比较结果的变量。

set(var1 "Hello")
set(var2 "World")string(COMPARE EQUAL "${var1}" "${var2}" result)
if(result)message(STATUS "The strings are equal")
else()message(STATUS "The strings are not equal")
endif()string(COMPARE LESS "${var1}" "${var2}" result)
if(result)message(STATUS "var1 is less than var2")
else()message(STATUS "var1 is not less than var2")
endif()string(COMPARE GREATER "${var1}" "${var2}" result)
if(result)message(STATUS "var1 is greater than var2")
else()message(STATUS "var1 is not greater than var2")
字符串连接

字符串连接也有两种方法。
一种方法是通过 set 命令直接将多个字符串变量或值连接起来。

set(STR1 "Hello, ")
set(STR2 "world!")
set(FULL_STR "${STR1}${STR2}")
message(STATUS "完整字符串:${FULL_STR}")

另一个连接字符串的方法是使用string(CONCAT <output_variable> <input> …)命令。

将所有 <input> 字符串拼接起来,结果存储在 <output_variable>

set(STR1 "Hello, ")
set(STR2 "World!")
string(CONCAT CONNECTED_STR ${STR1} ${STR2})
message(STATUS "Connected string: ${CONNECTED_STR}")
字符串替换

使用string(REPLACE <match_string> <replace_string> <output_variable> <input>) 替换字符串中的某部分。

<input>字符串中搜索 <match_string> 并将其替换为<replace_string>,结果存储在 <output_variable> 中。

set(MY_STRING "Hello CMake world")
string(REPLACE "CMake" "awesome" MY_STRING_MODIFIED ${MY_STRING})
message(STATUS "Modified String: ${MY_STRING_MODIFIED}")
字符串长度

获取字符串长度使用 string(LENGTH <string> <output_variable>)

用来计算字符串<string> 的长度,并将结果存储在<output_variable> 中。

set(MY_STR "Hello, world!")
string(LENGTH "${MY_STR}" MY_STR_LENGTH)
message(STATUS "字符串长度: ${MY_STR_LENGTH}")
字符串截取

提取子字符串使用 string(SUBSTRING <string> <begin> <length> <output_variable>)

提取 <string> 的子字符串,从 <begin> 开始,长度为 <length>,结果存储在 <output_variable> 中。

set(MY_STR "Hello, world!")
string(SUBSTRING "${MY_STR}" 0 5 SUB_STR)
message(STATUS "子字符串: ${SUB_STR}")  # 输出应为 "Hello"
字符串转换大小写

把字符串转换为全部大写string(TOUPPER <string> <output_variable>),将 <string> 转换为大写,结果存储在<output_variable>中。

把字符串转换为全部小写string(TOLOWER <string> <output_variable>),将 <string> 转换为小写,结果存储在<output_variable>中。

set(MY_STR "Hello, World!")
string(TOUPPER "${MY_STR}" MY_STR_UPPER)
string(TOLOWER "${MY_STR}" MY_STR_LOWER)
message(STATUS "大写: ${MY_STR_UPPER}")  # 输出全部大写
message(STATUS "小写: ${MY_STR_LOWER}")  # 输出全部小写
字符串正则表达式匹配和替换

使用正则表达式匹配和替换字符串的某些部分string(REGEX REPLACE <regex> <replace_expression> <output_variable> <input>)

<input> 使用正则表达式 <regex> 进行查找,并用<replace_expression> 进行替换,结果存储在 <output_variable> 中。

set(MY_STR "The quick brown fox")
string(REGEX REPLACE "quick brown" "slow red" MY_NEW_STR ${MY_STR})
message(STATUS "替换后的字符串: ${MY_NEW_STR}")  # 输出 "The slow red fox"
字符串查找子字符串

在字符串中查找一个子字符串string(FIND <string> <substring> <output_variable> [REVERSE])

<string> 中查找 <substring> 的位置,位置基础是从0开始,结果是<substring> 开始的索引,存储在 <output_variable> 中,如果没找到,输出 -1。可选的[REVERSE]参数表示从字符串的末尾开始向前搜索。使用REVERSE选项对于查找最后一次出现的位置特别有用,尤其是在处理包含多个相同子字符串的长字符串时。这提供了一种灵活的方式来从不同的方向分析和处理字符串数据。

set(MY_STRING "Hello World")
string(FIND "${MY_STRING}" "World" MY_INDEX)
message(STATUS "Index: ${MY_INDEX}") # 输出为Index: 6set(MY_STRING "Hello World, Hello Universe")
string(FIND "${MY_STRING}" "Hello" MY_INDEX REVERSE)
message(STATUS "Last index: ${MY_INDEX}") # 输出应该是13
字符串中查找正则表达式匹配的内容

在字符串中查找正则表达式匹配的内容string(REGEX MATCH <regular_expression> <output variable> <input_string> )

使用正则表达式 <regular_expression> 匹配 <input_string> 字符串,结果存储在<output_variable> 中。如果有匹配,该变量<output_variable>将包含匹配的文本;否则,它将是空的。

或者是用于匹配所有匹配项的变种:string(REGEX MATCHALL <regular_expression> <output_variable> <input_string>)

set(INPUT_STRING "The quick brown fox jumps over the lazy dog")
string(REGEX MATCH "quick.*fox" MATCHED_STRING ${INPUT_STRING})
message(STATUS "Matched string: '${MATCHED_STRING}'")

这段代码会把 MATCHED_STRING 设置为 quick brown fox,因为这是 <input_string> 中第一个匹配 <regular_expression> 的部分。REGEX MATCHALL 的行为类似,但它会找到所有匹配的实例而不仅仅是第一个。这很有用,特别是当你需要从输入字符串中提取一系列的匹配数据时。

# 设置包含数字的文本字符串
set(input_text "The 2 quick brown foxes jump over 13 lazy dogs 8 times.")# 使用正则表达式匹配所有数字
string(REGEX MATCHALL "[0-9]+" matched_numbers ${input_text})# 打印匹配到的所有数字
message("Matched numbers are: ${matched_numbers}")
字符串附加

字符串附加另一个字符串string(APPEND <variable> <string> [<string>...])

将一个或多个 <string> 附加到变量 <variable> 的值上

# 初始为空的编译标志
set(COMPILER_FLAGS "")# 根据需要附加标志
string(APPEND COMPILER_FLAGS "-Wall ")
string(APPEND COMPILER_FLAGS "-Werror ")
string(APPEND COMPILER_FLAGS "-O3")# 打印最终的编译标志
message(STATUS "Compiler flags: ${COMPILER_FLAGS}")

注意事项:

1、在指定多个值进行追加时,string(APPEND …)不会在这些值之间自动添加任何分隔符。如果需要分隔符(如空格或其他字符),你必须自己包括它们在值中。
2、和大部分CMake命令一样,string(APPEND …)修改变量的作用是在原地执行的,意味着它直接改变了传入的变量而不是返回一个新的修改后的副本。

字符串连接CONCAT和字符串附加APPEND的区别
CMake中的string(APPEND ...)string(CONCAT ...)命令都是用于处理字符串的,但它们在功能上有一些区别:
1、string(APPEND …)
string(APPEND …)命令用于向一个已经存在的变量追加内容。使用这个命令,我们可以向一个字符串变量的末尾添加更多的文本。这个操作是就地完成的,即对原有变量的内容直接进行扩展。

语法:

string(APPEND <variable> <value> [<value>...])

例子:

set(MY_STRING "Hello")
string(APPEND MY_STRING ", World!")
# 在这里,MY_STRING的值变成了"Hello, World!"

2、string(CONCAT …)
相比之下,string(CONCAT …)命令用于将多个字符串值合并为一个新的字符串。它不修改任何原有的字符串变量,而是创建一个新的字符串结果。
语法:

string(CONCAT <variable> <value> [<value>...])

例子:

set(STR1 "Hello")
set(STR2 ", ")
set(STR3 "World!")
string(CONCAT MY_NEW_STRING ${STR1} ${STR2} ${STR3})
# 在这里,创建了一个新的变量MY_NEW_STRING,其值为"Hello, World!"

总结:

1、string(APPEND …)是用来修改已存在变量的内容,通过追加方式扩展该变量的字符串值。
2、string(CONCAT …)是用于合并多个字符串值创建一个新的字符串变量,原有变量的值不会改变。
3、在选择使用哪一个的时候,可以根据你的具体需求来决定:如果你想要修改已有变量的值,可以使用APPEND;如果你想保留原有变量不变,而创建一个新的字符串,那么CONCAT会是更好的选择。

以上为一些基础的示例,实际应用中可能需要根据具体需求组合使用这些命令。CMake 的字符串操作十分灵活,掌握好这些基础操作,可以帮助你更好地管理和处理项目中的字符串数据。

三 、示例

以上源码地址:CMake从入门到实战系列(九)——CMake中的字符串处理指令和运算符
编译结果:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/620774.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Git教程】(十)版本库之间的依赖 —— 项目与子模块之间的依赖、与子树之间的依赖 ~

Git教程 版本库之间的依赖 1️⃣ 与子模块之间的依赖2️⃣ 与子树之间的依赖&#x1f33e; 总结 在 Git 中&#xff0c;版本库是发行单位&#xff0c;代表的是一个版本&#xff0c;而分支或标签则只能被创建在版本库这个整体中。如果一个项目中包含了若干个子项目&#xff0c;…

【Java】图片处理工具ImageMagick简介及其在Java中的应用

ImageMagick是一款强大的图像处理软件&#xff0c;它可以用于创建、编辑、合并和转换图像。它支持超过200种图像格式&#xff0c;并且提供了丰富的功能&#xff0c;包括图像缩放、旋转、裁剪、加水印、添加特效等。ImageMagick还支持批量处理图像&#xff0c;可以通过命令行或者…

PUBG绝地求生加速器用哪个好 最新带来绝地求生好用的加速器推荐

PUBG绝地求生加速器用哪个好 最新带来绝地求生好用的加速器推荐 绝地求生作为一款非常流行的游戏&#xff0c;吸引了全球亿万玩家的关注。相信大部分玩家都曾经在游戏中遇到过卡顿掉帧以及无法连接服务器的情况&#xff0c;&#xff0c;这对于游戏体验来说是非常不好的。今天…

上位机图像处理和嵌入式模块部署(用树莓派4b开发固件)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 嵌入式开发的领域其实很广&#xff0c;有上位机、驱动和bsp移植。较早之前&#xff0c;由于自己曾经在芯片公司上班&#xff0c;所以对uboot、linu…

Ant Design 表单基础用法综合示例

Ant Design 的表单组件设计得非常出色,极大地简化了表单开发的复杂度,让开发者能够快速构建出功能丰富、交互友好的表单界面。 接下来总结一下 Ant Design 中表单的基本用法。 Form 组件 用于定义整个表单,可以设置表单的布局方式、提交行为等。通常会将表单字段组件嵌套在 F…

Qt-绘制多边形、椭圆、多条直线

1、说明 所有的绘图操作是在绘图事件中进行。mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow>QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACEclass MainWindow : public QMainWindow {Q_OBJECTpublic:MainWi…

54Max09116-源代码 刚出max的第一个版本

54Max09116-源代码 刚出max的第一个版本 参考资料&#xff1a; 54Max09116-源代码 刚出max的第一个版本_98999NET源码资源网

SpringCloud框架 服务拆分和远程调用

数据库隔离避免耦合度过高&#xff0c;不同模块将自己的业务暴露为接口&#xff0c;供其他微服务调用 微服务远程调用技术Rest 在后端实现发送http请求 1.在启动类/配置类里注册RestTemplate启动对象 2.注入Bean对象使用

HTML5 新增语义标签及属性

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;HTML5和CSS3悦读 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; 文章目录 ✍HTML5 新增语义标签及属性&#x1f48e;1 HTML5 新增的块级语义化标签&…

【word】文档标题如何自动编号

我在写一个word文档的时候&#xff0c;每一级标题的格式都设置好了&#xff0c;包括字体&#xff0c;大小等等&#xff0c;但是如何自动编号呢&#xff1f; 在写中期报告的时候&#xff0c;我对每一级标题的格式都创建了一个单独的样式&#xff0c;像这样&#xff1a; 对于每一…

OSCP靶场--Validator

OSCP靶场–Validator 考点 1.nmap扫描 ## ┌──(root㉿kali)-[~/Desktop] └─# nmap -sV -sC 192.168.227.253 -p- -Pn --min-rate 2500 Starting Nmap 7.92 ( https://nmap.org ) at 2024-04-15 04:13 EDT Warning: 192.168.227.253…

通过Omnet++官网tictoc教程学习在Omnet++中构建和运行仿真 Part3

TicToc Part3 增强2节点 TicToc增加图标增加 日志添加状态变量增加参数使用NED 继承模拟处理延时随机数字和参数超时、取消计时器重传同样的消息 官方文档 在官方文档中&#xff0c;你可以看见所有的代码 增强2节点 TicToc 增加图标 为了使模型在GUI中看起来更好看&#xff…