[英]Excluding lines containing a specific string from REGEX REPLACE in CMake
This is my first post but I have been using StackOverflow for years. 这是我的第一篇文章,但多年来我一直在使用StackOverflow。 Thanks for helping me every time. 感谢您每次的帮助。
I am writing a script in CMake that is supposed to rewrite a portion of a .cfg file (it is the resources.cfg file from Ogre 3D engine) so that: 我正在CMake中编写一个脚本,该脚本应该重写.cfg文件的一部分(它是Ogre 3D引擎的resources.cfg文件),以便:
I will focus only on the first part, since they are both similar. 我将只关注第一部分,因为它们两者相似。 This is the resource file I am working on: 这是我正在处理的资源文件:
# Resources required by the sample browser and most samples.
[Essential]
Zip=stufftochange/media/packs/SdkTrays.zip
# Resource locations to be added to the default path
[General]
FileSystem=../media #local
FileSystem=stufftochange/media/materials/scripts
FileSystem=stufftochange/media/materials/textures
FileSystem=stufftochange/media/models
FileSystem=stufftochange/media/materials/programs/HLSL_Cg
FileSystem=stufftochange/media/materials/programs/GLSL
My current strategy is that only lines without the #local identifier should be affected by the REGEX REPLACE
statement. 我当前的策略是,只有没有#local标识符的行才应受到REGEX REPLACE
语句的影响。 My current code is: 我当前的代码是:
file(READ ${CMAKE_SOURCE_DIR}/cfg/resources.cfg RESOURCES_FILE)
string(REGEX REPLACE
"/media"
"${OGRE_HOME_BACKSLASHES}/media"
RESOURCES_FILE_MODIFIED ${RESOURCES_FILE})
file(WRITE ${CMAKE_SOURCE_DIR}/cfg/resources.cfg ${RESOURCES_FILE_MODIFIED})
which basically replaces all /media
occurrences. 基本上取代了所有/media
事件。 I need to replace the stufftochange
(that can be ANYTHING that is before string media
) only if #local
is not at the end of the line. 仅在#local
不在行末时,我才需要替换一下stufftochange
(可以是字符串media
之前的任何东西)。 I tried to modify the matching expression in lots of ways but, when I do, only the first and last line are replaced properly. 我试图以多种方式修改匹配的表达式,但是当我这样做时,只有第一行和最后一行被正确替换。 I suspect that it has to do with the line endings. 我怀疑这与行尾有关。
These are some of the expressions I tried, without luck: 这些是我尝试过的一些表达式,没有运气:
([^ #]*)=[^ ]*/media([^#\n$]*)
=[^ ]*/media([^#\n$]*)
/media([^# ]*)
/media([^#\n ]*)
Of course I used \\\\1
and \\\\2
to save the parts of the string that I want to keep. 当然,我使用\\\\1
和\\\\2
来保存要保留的字符串部分。
I did a few searches on google and stackoverflow but couldn't find a proper solution or guide for using CMake's regex replace (and documentation is very basic). 我在google和stackoverflow上进行了一些搜索,但是找不到使用CMake的正则表达式替换的正确解决方案或指南(并且文档非常基础)。 Any idea what my holy grail match expression would be? 知道我的圣杯比赛表情是什么吗?
CMake's regex syntax and documentation are pretty limited. CMake的正则表达式语法和文档非常有限。 I'd favour turning the file's contents into a list of strings, each string being a line in the file. 我倾向于将文件的内容转换为字符串列表,每个字符串都是文件中的一行。 Iterating these makes the regex much simpler: 迭代这些使正则表达式简单得多:
set(SourceFile "${CMAKE_SOURCE_DIR}/cfg/resources.cfg")
file(READ ${SourceFile} Contents)
# Set the variable "Esc" to the ASCII value 27 - basically something
# which is unlikely to conflict with anything in the file contents.
string(ASCII 27 Esc)
# Turn the contents into a list of strings, each ending with an Esc.
# This allows us to preserve blank lines in the file since CMake
# automatically prunes empty list items during a foreach loop.
string(REGEX REPLACE "\n" "${Esc};" ContentsAsList "${Contents}")
unset(ModifiedContents)
foreach(Line ${ContentsAsList})
# Don't modify the line if it contains #local at the end.
if(NOT "${Line}" MATCHES "#local${Esc}$")
string(REGEX REPLACE "=.*/media" "=${OGRE_HOME_BACKSLASHES}/media" Line ${Line})
endif()
# Swap the appended Esc character back out in favour of a line feed
string(REGEX REPLACE "${Esc}" "\n" Line ${Line})
set(ModifiedContents "${ModifiedContents}${Line}")
endforeach()
file(WRITE ${SourceFile} ${ModifiedContents})
If you don't care about preserving blank lines, you can use file(STRINGS ...)
to read in the file, which makes life a bit simpler: 如果您不关心保留空白行,则可以使用file(STRINGS ...)
来读取文件,这使工作变得更简单:
set(SourceFile "${CMAKE_SOURCE_DIR}/cfg/resources.cfg")
file(STRINGS ${SourceFile} Contents)
unset(ModifiedContents)
foreach(Line ${Contents})
# Don't modify the line if it contains #local at the end.
if(NOT "${Line}" MATCHES "#local$")
string(REGEX REPLACE
"=.*/media"
"=${OGRE_HOME_BACKSLASHES}/media"
Line ${Line})
endif()
set(ModifiedContents "${ModifiedContents}${Line}\n")
endforeach()
file(WRITE ${SourceFile} ${ModifiedContents})
Probably the best description of CMake's regex syntax is found in the docs for string
. 可能在docs文档中找到string
的CMake regex语法的最佳描述。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.