I’m trying to detecting when a path contains ..
For example:
D:/foobar/../
However I can’t seem to write the correct regex.
# regex.cmake
cmake_minimum_required(VERSION 3.21)
if ("D:/foobar" MATCHES "\.\.")
message(STATUS "${CMAKE_MATCH_0}")
endif()
if ("D:/foobar/../" MATCHES "\.\.")
message(STATUS "${CMAKE_MATCH_0}")
endif()
I run this regex and it somehow matches in both cases.
> cmake -P .\regex.cmake
-- D:
-- D:
Why is this happening?
The docs say you can use backslash to escape the .
character:
McMartin
(Alain Martin)
3
The documentation is a bit misleading. You basically need to escape “twice”. Once for the CMake parser itself, and once for the regex engine.
For instance, if you write
if ("D:\\foobar" MATCHES "\\")
message(STATUS "${CMAKE_MATCH_0}")
endif()
then the regex engine actually gets \
, which is not a valid regex, and you get an error like:
RegularExpression::compile(): Trailing backslash.
RegularExpression::compile(): Error in compile.
CMake Error at D:/dev/CMExt/regex.cmake:3 (if):
if given arguments:
"D:\\foobar" "MATCHES" "\\"
Regular expression "\" cannot compile
In your case, you need to write:
if ("D:/foobar/../" MATCHES "\\.\\.")
message(STATUS "${CMAKE_MATCH_0}")
endif()
I hope this helps!
3 Likes
jtxa
(Josef Angstenberger)
4
As an alternative you can use a bracket argument [[\.\.]]
intead of a quoted argument "\\.\\."
.
This makes writing RegExes simplier.
This is mentioned in the last sentence of the Regex Specification. Perhaps the docs should mention the right escaping at the top of the chapter.
3 Likes