18

I am trying to replace forwardslashes with backslashes. To do that i have the following line of code:

STRING(REGEX REPLACE "/" "\\" SourceGroup ${SourceGroupPath} )

SourceGroupPath = A/File/Path. SourceGroup is the variable to set the result to.

The problem i am having is with, the "\\" part to the code. I have tried several ways to getting to use the backslash literal like "\\" and using unicode but nothing seems to work.

The error i get in CMake is:

CMake Error at CMakeLists.txt:41 (STRING): string sub-command REGEX, mode REPLACE: replace-expression ends in a backslash.

Can someone please help me out?

Thanks,

Wouter

WoutervD
  • 2,139
  • 2
  • 13
  • 13

2 Answers2

28

The reason is that in a CMake string literal, the backslash is an escape character (just like in C, Java or JavaScript) and in regex, the backslash is an escape character as well.

So to represent a regex as a string literal, you need double escaping. (That's why many "higher level" languages have regex literal notation, BTW.)

The string literal "\\" represents the in-memory string "\" and that's an invalid regex, hence the "ends in a backslash" error.

The string literal "\\\\" represents "\\" in memory which is a valid regex (representing a single backslash).

Tomalak
  • 332,285
  • 67
  • 532
  • 628
  • 1
    what about forward slash? – Abid Rahman K Jun 05 '14 at 14:17
  • 2
    The forward slash has no meaning in regular expressions. It *might* have a meaning in the host language, but only if the host language uses forward slashes to delimit regex literals. In this case it must be escaped within the regex literal. (Many host languages work that way, so that you might come to think that the forward slash is somehow special in regular expressions. It's not.) – Tomalak Jun 05 '14 at 14:29
  • Result is `string(REGEX REPLACE "/" "\\\\" SourceGroup ${SourceGroup})` – Maxim Suslov Apr 06 '15 at 17:10
  • The reasoning about need for double escapes is right, but this has nothing to do with C string literals - that's CMake code in the question, not C. – Angew is no longer proud of SO May 06 '15 at 07:03
  • @Angew I take it that CMake strings work like C strings? – Tomalak May 06 '15 at 07:09
  • @Tomalak In this regard, yes, the principle is the same - backslash is an escape character. – Angew is no longer proud of SO May 06 '15 at 07:13
  • [Here](http://www.cmake.org/cmake/help/v3.2/manual/cmake-language.7.html#escape-sequences) is available the grammar description for cmake – Antonio May 06 '15 at 07:16
  • Okay. In any case you are right, it was imprecise of me. I've corrected my post. – Tomalak May 06 '15 at 07:24
15

This is a simpler way to do it:

file(TO_NATIVE_PATH ${MYPATH} MYPATH)
Roman R.
  • 68,205
  • 6
  • 94
  • 158
lgwest
  • 1,347
  • 5
  • 16
  • 26
  • 1
    Some build environments (such as MSYS) get mixed up and manual path conversion is needed due to 3rd party executables expecting non-posix style paths, hence the need for manual string replacement. – tresf Aug 01 '15 at 02:20