-1

I need a C++ function (or object) able to tell me if a certain string is an ANSI escape sequence.

So, if I have for example:

std::string ansi = "\033[0m";

I would need something like this:

is_escape_char( ansi )

which returns false or true if the string is an ANSI escape sequence. Is it possible?

Gianluca Bianco
  • 656
  • 2
  • 11
  • Does this answer your question? [Filtering out ANSI escape sequences](https://stackoverflow.com/questions/13506033/filtering-out-ansi-escape-sequences) – xtay2 Jul 19 '22 at 21:06
  • @xtay2 no, I need a C++ function, not a Python one. – Gianluca Bianco Jul 19 '22 at 21:08
  • I'm sure it's possible, but obviously the first thing is to define `ANSI escape sequence' which doesn't seem to have any authoritative definition. – john Jul 19 '22 at 21:08
  • @GianlucaBianco it uses regex which is also supported/identical in c++ – xtay2 Jul 19 '22 at 21:08
  • @john let's simply say I want to be able to check if the string I defined is an ANSI escape sequence. So a solution for that single case. – Gianluca Bianco Jul 19 '22 at 21:09
  • @xtay2 could you please provide me a full answer with a C++ function? I will upvote and choose it as the correct one. – Gianluca Bianco Jul 19 '22 at 21:09
  • @GianlucaBianco You mean `bool is_escape_char(const std::string& ansi) { return ansi == "\033[0m"; }`? – john Jul 19 '22 at 21:10
  • Sorry, but Stackoverflow is not a coding service. I know zilch python, but that Python code looks simple enough to translate into C++, as is. – Sam Varshavchik Jul 19 '22 at 21:11
  • @GianlucaBianco You asked if it was "possible" and C++ is a Turing-complete language so, by definition, if it is possible in a different language it is possible in C++. And, you can't be asking how to do it because the Python answer would give you that. So are you really asking if one of us can transliterate the Python code into C++ code for you? I don't mind doing it but I don't want to waste the effort if that's not really what you are asking. – Jerry Jeremiah Jul 19 '22 at 21:11
  • @JerryJeremiah yes, if someone can translate it for me it would be a great help, and would provide the final answer of course – Gianluca Bianco Jul 19 '22 at 21:12
  • Does your function need to distinguish between things that LOOK like escape sequences (which the regex answer below would match) and actual escape sequences which would actually work on a particular device (not all devices support all sequences) – Jerry Jeremiah Jul 19 '22 at 21:29
  • @JerryJeremiah yes, exactly – Gianluca Bianco Jul 19 '22 at 21:41
  • @GianlucaBianco The problem is, for example, for the cursor positioning ones you would need to also pass in the number of rows and columns that the terminal has - because if it doesn't have that many rows or columns the escape sequence won't work even though it LOOKS valid. – Jerry Jeremiah Jul 19 '22 at 21:52
  • @GianlucaBianco Also, some of the private modes are supported by most physical terminal and not by multiplexers like tmux, so you would have to pass in some info to identify the program/terminal type that is being used. – Jerry Jeremiah Jul 19 '22 at 21:56
  • This looks helpful for someone who wants to write such a thing: https://gist.github.com/fnky/458719343aabd01cfb17a3a4f7296797 It will almost certainly not be complete but it looks pretty comprehensive to me. – Jerry Jeremiah Jul 19 '22 at 21:57

2 Answers2

1

Take a look at regular expressions in C++.

The regex for an any ANSI escape sequence is: \033\[((?:\d|;)*)([a-zA-Z]).

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
xtay2
  • 453
  • 3
  • 14
1

If you know it's at the start of the string

bool is_escape_char(std::string_view str)
{
   return str.starts_with("\033");
}

Otherwise look for it anywhere in the string

bool is_escape_char(std::string_view str)
{
   return std::string_view::npos != str.find("\033");
}

Depending on what you need, you can capture the index in the return of 'find', determine which sequence it is, and find the next code that finishes the sequence. But it requires inspection of the characters following the initial escape.

  • The second one works perfectly! First one gives me an error: `other.cpp:11:15: error: ‘using string_view = class std::basic_string_view’ {aka ‘class std::basic_string_view’} has no member named ‘starts_with’ 11 | return str.starts_with("\033");` – Gianluca Bianco Jul 20 '22 at 07:50
  • 1
    That method is new to C++20 https://en.cppreference.com/w/cpp/string/basic_string_view/starts_with – Jesse Maurais Jul 21 '22 at 12:28
  • Actually, this answer gives incorrect results, because it matches *any* escape-character, whether or not it begins an *ANSI escape sequence*. – Thomas Dickey Jul 23 '22 at 11:19
  • That's true. There are many second characters that can follow the initial escape to indicate an ANSI escape sequence. You'd have to check that the following character is one among them. But if you check for "\033[0m" as in the OP, then you only match the SGR reset sequence. And "\033[" will only match CSI sequences. Curiously, in what case does the presence of an escape character not begin an ANSI escape sequence? – Jesse Maurais Jul 24 '22 at 15:00