首页 > 解决方案 > 如何在 CMake 中删除字符串中的一行文本,解决 CMake 缺乏基于行的正则表达式匹配的问题?

问题描述

我发现 CMake 并没有按照我预期的方式执行 RegEx。 显然,其他人也遇到了同样的问题。问题是 CMake 不是基于行的。当您使用^or$运算符时,它们作用于整个字符串,而不是一行的开头和结尾。

我正在尝试删除文件中所有说#include <blah.h>or的行#include "blah.h"

为此,我创建了一个小函数:

function(deleteinplace IN_FILE pattern)
    file(READ ${IN_FILE} CONTENTS)
    string(REGEX REPLACE ${pattern} "" STRIPPED ${CONTENTS})
    file(WRITE ${IN_FILE} "${STRIPPED}")
endfunction()

然后调用它:

deleteinplace(myfile.h "\#include.*\n")

这最终会在字符串匹配后删除文件中的所有内容。

.*?出于某种原因,像在 CMake 中不起作用的非贪婪技巧。其他类似的技巧\r?\n也不起作用。

我需要解决这个问题。

标签: regexcmake

解决方案


诀窍不是file(READ ...),而是file(STRINGS ....)。这将允许CMake逐行读取文件,并返回一个字符串列表,每个字符串代表一行,完全符合您的需要。使用这种方法,您的函数将如下所示:

function(deleteinplace IN_FILE pattern)
  # create list of lines form the contens of a file
  file (STRINGS ${IN_FILE} LINES)

  # overwrite the file....
  file(WRITE ${IN_FILE} "")

  # loop through the lines,
  # remove unwanted parts 
  # and write the (changed) line ...
  foreach(LINE IN LISTS LINES)
    string(REGEX REPLACE ${pattern} "" STRIPPED "${LINE}")
    file(APPEND ${IN_FILE} "${STRIPPED}\n")
  endforeach()
endfunction()

然后调用它:

deleteinplace(myfile.h "\#include.*")

请注意,在此示例\n中,作为语句的一部分自动从行中剥离file(STRINGS ....),并在语句中添加回file(APPEND ....);因此,\n在调用函数时也从搜索模式中删除。

最后,这里是关于file(STRINGS ...)的文档


推荐阅读