Jump to content
Chimp

regexp and ANSI escape sequences

Recommended Posts

Chimp

regex and iso escape sequences

Hi, I would like to extract all ISO escape squences embedded in a string and separate them from the rest of the string, still keeping the information about their position, so that, for exemple, a string like this one (or even more complex):

(the string could start with normal text or iso sequences)
 

'\u001B[4mUnicorn\u001B[0m'

should be 'transformed' in an array like this

$a[0] = '\u001B[4m'   ; first iso escape sequence
$a[1] = 'Unicorn'     ; normal text
$a[2] = '\u001B[4m'   ; second iso escape sequence
... and so on

(note: the above escape sequence has 'control codes' marked as "\u001B' for the asc "esc" char for exemple and a similar notation is also used for other control chars, but in the real string to be parsed those control chars  are embedded  as a single byte with a value from 01 to 31). at this link (http://artscene.textfiles.com/ansi/) there are many example of real ANSI text files .

searching on the web I've found some possible solutions that make use of regexp to achieve similar purpose, and above some others, the regexp pattern posted in the following link by kfir (https://stackoverflow.com/questions/14693701/how-can-i-remove-the-ansi-escape-sequences-from-a-string-in-python) seems to be able to catch a wider range of ISO escape sequences (not only color sequences), but my lack of skills on regexp, prevents me from evaluating and testing such patterns
I would be very grateful if some regexp guru could come to my rescue...

thanks everybody  for reading...

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Bilgus

I discovered that while you can cajole regexp into giving you a position of arbitrary escape sequences it is way slower than just walking the string using stringinstr like on the order of 2:1 or 3:1

better off doing this 

Local $yourstr = "Mytest" & Chr(1) & "String" & Chr(0) & "Mytest" & Chr(3) & "String" & "Mytest" & Chr(31) & "String"
;------------------------------
Local Const $STR_CASESENSE = 0
Local $sMatch
For $i = 0 To 31
    $sMatch &= Chr($i)
Next

For $i = 1 To StringLen($yourstr)
    $sChr = StringMid($yourstr, $i, 1)
    If StringInStr($sMatch, $sChr, $STR_CASESENSE) > 0 Then ;(note the casesense)
        ConsoleWrite("Esc \" & Asc($sChr) & " @ Pos:" & $i & @CRLF)
        ;More Processing
    EndIf
Next
;---------------------------------------------------------
;OR Faster

For $i = 1 To BinaryLen($yourstr)
    $iChr = BinaryMid($yourstr, $i, 1)

    If $iChr < 32 Then
        ConsoleWrite("Esc " & $iChr & " @ Pos:" & $i & @CRLF)
        ;More Processing
    EndIf
Next
Esc \1 @ Pos:7
Esc \0 @ Pos:14
Esc \3 @ Pos:21
Esc \31 @ Pos:34
Esc 0x01 @ Pos:7
Esc 0x00 @ Pos:14
Esc 0x03 @ Pos:21
Esc 0x1F @ Pos:34

 

Edited by Bilgus

Share this post


Link to post
Share on other sites
Chimp

thanks @Bilgus, for yor replay, but maybe I'm not been very clear of what I'm trying to achieve (sorry),
using your way I can catch all "single" control chars found along the string and get the location where was found, but an ISO "escape sequence" is a 'complex' set of more chars starting with the two bytes chr(27) & '[' and followed by a variable number of chars depending on the particular sequence itself. Now I would like to catch "any" of the many possible 'escape' sequences, splitting them from the whole string in a way as from post #1.

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Bilgus

Ah Sorry I misunderstood I thought you were looking for their start positions you want to split on them

Like maybe this

#include <Array.au3>


Local $yourstr = 'Regulartext' & CHR(0x1B) & '[40m' & CHR(0x1B) & '[2J' & CHR(0x1B) & '[2C' & CHR(0x1B) & '[0;34m³   ' & CHR(0x1B) & '[1;37m³   ' & CHR(0x1B) & '[0;34m³' & CHR(0x1B) & '[31mÜ' & CHR(0x1B) & '[33mßßß' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[31mßßßßßßßÛßßß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[31mß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[31mß' & CHR(0x1B) & '[33mßßß' & CHR(0x1B) & '[31mß' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÛßßßß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[31mß' & CHR(0x1B) & '[33mßßß' & CHR(0x1B) & '[31mÛßßßßßßßßÛßßßßß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[31mßÛßß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[31mß' & CHR(0x1B) & '[33mßß' & CHR(0x1B) & '[31mßßß' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[31mÜ' & CHR(0x1B) & '[34m³' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u   ³' & CHR(0x1B) & '[2;1H  ÄÄÄÄ' & CHR(0x1B) & '[1;37mÛ' & CHR(0x1B) & '[0;34mÄÄ' & CHR(0x1B) & '[31mÜ' & CHR(0x1B) & '[33mß' & CHR(0x1B) & '[34mÄ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[1;35mÜÛÛÛÛÛÛÛÛÜ ÛÛÛÛÛÛÛÛÛÛÛÜßÛÛÛÛÛÛÛß ÛÛÛÛÛÛÛ Ü²ÛÛÛÛ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÛÛÜßÛÛÛÛÛÛÛÛÛÜ' & CHR(0x1B) & '[0;33mßÜ' & CHR(0x1B) & '[34mÄ' & CHR(0x1B) & '[1;37mß' & CHR(0x1B) & '[0;34m³Ä' & CHR(0x1B) & '[3;1H  ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u³   ' & CHR(0x1B) & '[1;37mÛ  ' & CHR(0x1B) & '[0;33m±' & CHR(0x1B) & '[34m³' & CHR(0x1B) & '[1;35m²²ÛÛÛÛÛÛÛÛÛÝÛÛÛÛÛÛÛ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÛÛÛÛÛÛÜßÛÛÛß ÜÞÛÛÛ²ÛÛÛÞ²ÛÛÛ ²ÛÛÛÝÛÛÛÛÛÛÛÛÛÛÛÜ' & CHR(0x1B) & '[0;31mß' & CHR(0x1B) & '[sUnicorn' & CHR(0x1B) & '[u' & CHR(0x1B) & '[1;37mÛ' & CHR(0x1B) & '[4;1H  ' & CHR(0x1B) & '[0;34mÄÄ' & CHR(0x1B) & '[1mÄÄ' & CHR(0x1B) & '[37mÛ' & CHR(0x1B) & '[34mÄ' & CHR(0x1B) & '[30m°' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[0;33m°' & CHR(0x1B) & '[1;30m°' & CHR(0x1B) & '[35m±Û²ÛÛÛßßÞÛß ²Û²Û' & CHR(0x1B) & '[30m°°±±² ' & CHR(0x1B) & '[35mÜ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÜÜÜÜÛß Ü²ÛÞßÞ²Û²Û Þ±²ÛÛ ±²ÛÛݲÛÛ' & CHR(0x1B) & '[30m°°±²' & CHR(0x1B) & '[35mÛÛÛÛÛ' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[30m°' & CHR(0x1B) & '[37mÛ' & CHR(0x1B) & '[30m±' & CHR(0x1B) & '[0;34mÄ' & CHR(0x1B) & '[5;1H  ' & CHR(0x1B) & '[1;37mÜ  ' & CHR(0x1B) & '[30m°' & CHR(0x1B) & '[s' & CHR(0x1B) & '[u' & CHR(0x1B) & '[37mÛ' & CHR(0x1B) & '[30m°±' & CHR(0x1B) & '[37mÜ' & CHR(0x1B) & '[30m°' & CHR(0x1B) & '[35m°±²²ÛBLAG  þß   ²±ÛÛ ÛÜ   ²Û' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÛÛß °±²²Û  Þ±²ÛÛ' & CHR(0x1B) & '[30m²' & CHR(0x1B) & '[35mÞ°±²Û ²²ÛÛݱ²Û' & CHR(0x1B) & '[30mÄ' & CHR(0x1B) & '[0;34m' & CHR(0x1B) & '[s' & CHR(0x1B) & '[uÄ' & CHR(0x1B) & '[1;35mÜÛÛÛÛßXKCD?' & CHR(0x1B) & '[30m°' & CHR(0x1B) & '[0;33mÜ' & CHR(0x1B) & ''
;------------------------------
$aMatch = StringRegExp($yourstr, "[^\x1B]++|\x1B\[[0-?]*[ -/]*[@-~]", 3)
ConsoleWrite("Err:" & @Error & @CRLF)
;---------------------------------------------------------
_ArrayDisplay($aMatch)

I grabbed that regex from your linked stackoverflow page you could just '|' other beginning sequences as well

but if you can link me a good file that fails i can build it up a bit more

  • Like 1

Share this post


Link to post
Share on other sites
Chimp

hi @Bilgus, thanks for your regexp  pattern,
at first glance seems to work... I will make some 'intensive' testing...
p.s. You say you grabbed that pattern from the link I posted on post #1, since there are more patterns in that page, isn't the pattern located a bit down (the penultimate) posted by the user "kfir" able to catch a wider range of ISO escape sequences ? (I just say this becouse I see that that pattern is a longer one, and so i suppose thath  it makes a more accurate search?  ... just a wild guess). Thanks again.


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Bilgus

Idk the first one seems to match more but perhaps it has some non valid ones in the capture you can try this one it won't grab the non escape sequences but you can see if it gets any more than the first and let me know the format of the extras that are captured

(\e\[\??\d+[hl]|\e[=<>a-kzNM78]|\e[\(\)][a-b0-2]|\e\[\d{0,2}[ma-dgkjqi]|\e\[\d+;\d+[hfy]?|\e\[;?[hf]|\e#[3-68]|\e[01356]n|\eO[mlnp-z]?|\e/Z|\e\d+|\e\[\?\d;\d0c|\e\d;\dR)

also the first one can be rewritten as

[^\e]++|\e\[[0-?]*[ -/]*[@-~]

apparently \e is the escape character

Edited by Bilgus

Share this post


Link to post
Share on other sites
Bilgus

Ok So I found the list that other poster used to make his captures

I think this is about right

[^\e]++|\e\[?[!-\?]*[!-\/]*[0-~]*
#include <Array.au3>


Local $yourstr = "Regulartext" & CHR(0x1B) &  "[20h Set new line mode   LMN" & CHR(0x1B) &  "[?1h   Set cursor key to application   DECCKM none Set ANSI (versus VT52)  DECANM" & _
CHR(0x1B) &  "[?3h  Set number of columns to 132    DECCOLM" & CHR(0x1B) &  "[?4h   Set smooth scrolling    DECSCLM" & CHR(0x1B) &  "[?5h   Set reverse video on screen DECSCNM" & _
CHR(0x1B) &  "[?6h  Set origin to relative  DECOM" & CHR(0x1B) &  "[?7h Set auto-wrap mode  DECAWM" & CHR(0x1B) &  "[?8h    Set auto-repeat mode    DECARM" & _
CHR(0x1B) &  "[?9h  Set interlacing mode    DECINLM  " & CHR(0x1B) &  "[20l Set line feed mode  LMN" & CHR(0x1B) &  "[?1l   Set cursor key to cursor    DECCKM" & CHR(0x1B) &  _
"[?2l   Set VT52 (versus ANSI)  DECANM" & CHR(0x1B) &  "[?3l    Set number of columns to 80 DECCOLM" & CHR(0x1B) &  "[?4l   Set jump scrolling  DECSCLM" & CHR(0x1B) &  "[?5l   Set normal video on screen  DECSCNM" & _
CHR(0x1B) &  "[?6l  Set origin to absolute  DECOM" & CHR(0x1B) &  "[?7l Reset auto-wrap mode    DECAWM" & CHR(0x1B) &  "[?8l    Reset auto-repeat mode  DECARM" & CHR(0x1B) &  "[?9l    Reset interlacing mode  DECINLM  " & _
CHR(0x1B) &  "= Set alternate keypad mode   DECKPAM" & CHR(0x1B) &  ">  Set numeric keypad mode DECKPNM  " & CHR(0x1B) &  "(A   Set United Kingdom G0 character set setukg0" & CHR(0x1B) &  ")A Set United Kingdom G1 character set setukg1" & CHR(0x1B) &  "(B Set United States G0 character set  setusg0" & CHR(0x1B) &  ")B Set United States G1 character set  setusg1" & CHR(0x1B) &  "(0 Set G0 special chars. & line set    setspecg0" & CHR(0x1B) &  ")0   Set G1 special chars. & line set    setspecg1" & CHR(0x1B) &  "(1   Set G0 alternate character ROM  setaltg0" & CHR(0x1B) &  ")1    Set G1 alternate character ROM  setaltg1" & CHR(0x1B) &  "(2    Set G0 alt char ROM and spec. graphics  setaltspecg0" & CHR(0x1B) &  ")2    Set G1 alt char ROM and spec. graphics  setaltspecg1  " & CHR(0x1B) &  "N   Set single shift 2  SS2" & CHR(0x1B) &  "O  Set single shift 3  SS3  " & CHR(0x1B) &  "[m   Turn off character attributes   SGR0" & CHR(0x1B) &  "[0m   Turn off character attributes   SGR0" & CHR(0x1B) &  "[1m   Turn bold mode on   SGR1" & CHR(0x1B) &  "[2m   Turn low intensity mode on  SGR2" & CHR(0x1B) &  "[4m   Turn underline mode on  SGR4" & CHR(0x1B) &  "[5m   Turn blinking mode on   SGR5" & CHR(0x1B) &  "[7m   Turn reverse video on   SGR7" & CHR(0x1B) &  "[8m   Turn invisible text mode on SGR8  " & CHR(0x1B) &  "[Line;Liner Set top and bottom lines of a window    DECSTBM  " & CHR(0x1B) &  "[ValueA  Move cursor up n lines  CUU" & CHR(0x1B) &  "[ValueB    Move cursor down n lines    CUD" & CHR(0x1B) &  "[ValueC    Move cursor right n lines   CUF" & CHR(0x1B) &  "[ValueD    Move cursor left n lines    CUB" & CHR(0x1B) &  "[H Move cursor to upper left corner    cursorhome" & CHR(0x1B) &  "[;H Move cursor to upper left corner    cursorhome" & CHR(0x1B) &  "[Line;ColumnH   Move cursor to screen location v,h  CUP" & CHR(0x1B) &  "[f Move cursor to upper left corner    hvhome" & CHR(0x1B) &  "[;f Move cursor to upper left corner    hvhome" & CHR(0x1B) &  "[Line;Columnf   Move cursor to screen location v,h  CUP" & CHR(0x1B) &  "D  Move/scroll window up one line  IND" & CHR(0x1B) &  "M  Move/scroll window down one line    RI" & CHR(0x1B) &  "E   Move to next line   NEL" & CHR(0x1B) &  "7  Save cursor position and attributes DECSC" & CHR(0x1B) &  "8    Restore cursor position and attributes  DECSC  " & CHR(0x1B) &  "H  Set a tab at the current column HTS" & CHR(0x1B) &  "[g Clear a tab at the current column   TBC" & CHR(0x1B) &  "[0g    Clear a tab at the current column   TBC" & CHR(0x1B) &  "[3g    Clear all tabs  TBC  " & CHR(0x1B) &  "#3   Double-height letters, top half DECDHL"
Local $yourstr2 = CHR(0x1B) &  "#4  Double-height letters, bottom half  DECDHL" & CHR(0x1B) &  "#5  Single width, single height letters DECSWL" & CHR(0x1B) & _
"#6 Double width, single height letters DECDWL  " & CHR(0x1B) &  "[K    Clear line from cursor right    EL0" & CHR(0x1B) &  "[0K    Clear line from cursor right    EL0" & CHR(0x1B) &  "[1K    Clear line from cursor left EL1" & CHR(0x1B) &  "[2K    Clear entire line   EL2  " & CHR(0x1B) &  "[J   Clear screen from cursor down   ED0" & CHR(0x1B) &  "[0J Clear screen from cursor down ED0" & CHR(0x1B) & "[1J Clear screen from cursor up ED1" & _
 CHR(0x1B) &  "[2J Clear entire screen ED2  " & _
 CHR(0x1B) &  "5n Device status report DSR" & _
 CHR(0x1B) &  "0n Response: terminal is OK DSR" & _
 CHR(0x1B) &  "3n Response: terminal is not OK DSR  " & _
 CHR(0x1B) &  "6n Get cursor position DSR" & _
 CHR(0x1B) &  "Line;ColumnR Response: cursor is at v,h CPR  " & _
 CHR(0x1B) &  "[c Identify what terminal type DA" & _
 CHR(0x1B) &  "[0c Identify what terminal type (another) DA" & _
 CHR(0x1B) &  "[?1;Value0c Response: terminal type code n DA  " & _
 CHR(0x1B) &  "c Reset terminal to initial state RIS  " & _
 CHR(0x1B) &  "#8 Screen alignment display DECALN" & _
 CHR(0x1B) &  "[2;1y Confidence power up test DECTST" & _
 CHR(0x1B) &  "[2;2y Confidence loopback test DECTST" & _
 CHR(0x1B) &  "[2;9y Repeat power up test DECTST" & _
 CHR(0x1B) &  "[2;10y Repeat loopback test DECTST  " & _
 CHR(0x1B) &  "[0q Turn off all four leds DECLL0" & _
 CHR(0x1B) &  "[1q Turn on LED #1 DECLL1" & _
 CHR(0x1B) &  "[2q Turn on LED #2 DECLL2" & _
 CHR(0x1B) &  "[3q Turn on LED #3 DECLL3" & _
 CHR(0x1B) &  "[4q Turn on LED #4 DECLL4     Codes for use in VT52 compatibility mode" & _
 CHR(0x1B) &  "< Enter/exit ANSI mode (VT52) setansi  " & _
 CHR(0x1B) &  "= Enter alternate keypad mode altkeypad" & _
 CHR(0x1B) &  "> Exit alternate keypad mode numkeypad  " & _
 CHR(0x1B) &  "F Use special graphics character set setgr" & _
 CHR(0x1B) &  "G Use normal US/UK character set resetgr  " & _
 CHR(0x1B) &  "A Move cursor up one line cursorup" & _
 CHR(0x1B) &  "B Move cursor down one line cursordn" & _
 CHR(0x1B) &  "C Move cursor right one char cursorrt" & _
 CHR(0x1B) &  "D Move cursor left one char cursorlf" & _
 CHR(0x1B) &  "H Move cursor to upper left corner cursorhome" & _
 CHR(0x1B) &  "LineColumn Move cursor to v,h location cursorpos(v,h)" & _
 CHR(0x1B) &  "I Generate a reverse line-feed revindex  " & _
 CHR(0x1B) &  "K Erase to end of current line cleareol" & _
 CHR(0x1B) &  "J Erase to end of screen cleareos  " & _
 CHR(0x1B) &  "Z Identify what the terminal is ident" & _
 CHR(0x1B) &  "/Z Correct response to ident identresp       VT100 Special Key Codes These are sent from the terminal back to the computer when the particular key is pressed. Note that the numeric keypad keys send different codes in numeric mode than in alternate mode. See" & _
 CHR(0x1B) &  "ape codes above to change keypad mode.     Function Keys: " & _
 CHR(0x1B) &  "9 PF1" & _
 CHR(0x1B) &  "OQ PF2" & _
 CHR(0x1B) &  "OR PF3" & _
 CHR(0x1B) &  "OS PF4    Arrow Keys:    Reset Set up" & CHR(0x1B) &  "A" & CHR(0x1B) &  "OA down" & CHR(0x1B) &  "B" & CHR(0x1B) &  "OB right" & CHR(0x1B) &  "C" &  CHR(0x1B) &  "OC left" & CHR(0x1B) &  "D" & CHR(0x1B) &  "OD    Numeric Keypad Keys: " & _
 CHR(0x1B) &  "Op 0" & _
 CHR(0x1B) &  "Oq 1" & _
 CHR(0x1B) &  "Or 2" & _
 CHR(0x1B) & "Os 3" & _
 CHR(0x1B) & "Ot4" & _
 CHR(0x1B) & "Ou5" & _
 CHR(0x1B) & "Ov6" & _
 CHR(0x1B) & "Ow7" & _
 CHR(0x1B) & "Ox8" & _
 CHR(0x1B) & "Oy9" & _
 CHR(0x1B) & "Om-(minus)" & _
 CHR(0x1B) & "Ol,(comma)" & _
 CHR(0x1B) & "On.(period)" & _
 CHR(0x1B) & "OM^M    Printing: " & _
 CHR(0x1B) & "[iPrint ScreenPrint the current screen" & _
 CHR(0x1B) & "[1iPrint LinePrint the current line" & _
 CHR(0x1B) & "[4iStop Print LogDisable log" & _
 CHR(0x1B) & "[5iStart Print LogStart log; all received text is echoed to a printer"
;------------------------------
$aMatch = StringRegExp($yourstr & $yourstr2, "[^\e]++|\e\[?[!-\?]*[!-\/]*[0-~]*", 3)
ConsoleWrite("Err:" & @Error & @CRLF)
;---------------------------------------------------------
_ArrayDisplay($aMatch)

 

Share this post


Link to post
Share on other sites
Chimp

Hi @Bilgus, thanks for your post,

From a quick test I see that main problem is that ANSI escape sequences tested here ends all with a white space, while usually those doesn't end with a white space, (and nor with a lowercase 'm' as we could expect). the normal text following the escape sequence is directly attached to the end of the escape sequence without any spaces.
I think that this is the main difficulty, that is, identify the escape sequence embedded in the "middle" of text where the start of the sequence is marked by the 2 bytes "esc" + "[" while the end of the sequence depends from the particular sequence itself...

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Bilgus

Like I said If you can get me a sample file that shows exactly the conditions you need and where it fails I can create a regexp to match it but my output will only be as good as the input GIGO so to speak

Share this post


Link to post
Share on other sites
Chimp

according to what is esemplified at this link, http://man7.org/linux/man-pages/man4/console_codes.4.html (see the ECMA-48 CSI sequences section) ansi iso escape sequences shuld conform to the following "rules":

  1. start with the so called CSI characters (Control Sequence Introducer) that are nothing more that the 2 codes chr(27) & chr(91) that are "esc["
  2. following there can be: none, one or more decimal numbers separated by semicolons
  3. and at the end an alphabetic letter that terminates the sequence. upper or lowercase make difference. this final letter determines the action that is to be taken. (white spaces within the escape sequence, that is between <esc>  and the last char, should be ignored)

 

ch3examp2a

in short that's all.

The wished regexp should capture any sequence responding to points 1, 2 and 3 and return a global match array where "normal text" is returned in an element of the array, then as soon as an escape sequence is catched, it should be stored in the next element of the array, and following normal text in the next element of the array and so on till the end of text.
so, for example the following text
 

"Hello, " & chr(27) & "[ 40;31mThis is red on black " & chr(27) & "[ 47;32m And this is green on white"

should be "splitted" into the following array elements for example
 

[0] Hello,
[1] esc]40;31m
[2] This is red on black
[3] esc]47;32m
[4] And this is green on white

Another similar(?) regexp should instead remove all escape sequences from the whole string, leaving and returning only the "normal" text cleaned.

... I don't know if this above is GIGO, but ansi escape sequences works more or less like that. Are there regular expressions capable to produce the above array and the cleaned string??
sorry if I was a bit wordy...  any help I will be very welcome. Thank you on advance.

Edited by Chimp
inserted image

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
jchd

Don't know if that's GIGO below but I believe it fits the specs:

Local $s = "Hello, " & Chr(27) & "[ 40;31mThis is red on black " & _
            Chr(27) & "[ 47;32m And this is green on white" & _
            Chr(27) & "[ 47 ;  32   m And this is also green on white (more spaces)" & _
            Chr(27) & "[1234567890123456798Kvftio this matches the definition, albeit probably invalid ANSI escape" & _
            Chr(27) & "[ 47;32 !!!! this is not an ANSI sequence"
Local $aRes = StringRegExp($s, "(?x)" & _
                            "(?(DEFINE) (?<ANSI_Escape> \[\s*\d+\s* (?:;\s*\d+\s*)* [[:alpha:]]) )" & _
                            "(?| \x1B (?&ANSI_Escape) | (?:[^\x1B] (?!(?&ANSI_Escape)))+ )", 3)
_ArrayDisplay($aRes, "Mixed results")

Local $sClean = StringRegExpReplace($s, "(?x) (\x1B \[\s*\d+\s* (?:;\s*\d+\s*)* [[:alpha:]])",  "")
MsgBox(0, "Pure text", $sClean)

The advantage of using DEFINE in such regexp is that you can very explicitely specify what's what and give it a name, using a construct equivalent to a procedural programming language subroutine. Using (?x) allows unsignificant whitespaces in the regexp to make it easier to read/dissect/understand.

  • Like 1

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
Bilgus

@Jchd have you seen that spec lol

I think this should do it

"\x9b|\e\[[:<=>?]?[\d;]*[\x20-/]?[@-~]|\cX|\ea|\x9d|\e]|\x9f|\e_|\x90|\eP|\x9e|\e^(?:[\x0f\x0e\t-\r\x20-0x7e]*|[\xA0-\xFE\t-\r\x20-0x7e]*)\cG|\x9c|\e\\|\cX|\ea|x98|\eX[^\x98\x9c]*?\cG|\x9c|\e\\|\cX|\ea|\e[\x20-/]*(?:[0-~]|\cX|\ea)"

@Chimp you just aren't going to get a regexp that will do everything you want use this gather the esc sequences run it again replace them with a easy to use sentinel

Split on that sentinel and rebuild from there

I take no credit for that above regexp I used the definitions here to build it

https://metacpan.org/source/JOSEF/Ecma48-Util-0.01/lib/Ecma48/Util.pm

Share this post


Link to post
Share on other sites
Bilgus

Something like this

#include <Array.au3>
#include <StringConstants.au3>

;........
Local $sRegEsc = "\x9b|\e\[[:<=>?]?[\d;]*[\x20-/]?[@-~]|\cX|\ea|\x9d|\e]|\x9f|\e_|\x90|\eP|\x9e|\e^(?:[\x0f\x0e\t-\r\x20-0x7e]*|[\xA0-\xFE\t-\r\x20-0x7e]*)\cG|\x9c|\e\\|\cX|\ea|x98|\eX[^\x98\x9c]*?\cG|\x9c|\e\\|\cX|\ea|\e[\x20-/]*(?:[0-~]|\cX|\ea)";;;

Local $aMatch = StringRegExp($yourstr, $sRegEsc, 3)
ConsoleWrite("Err:" & @error & @CRLF)

Local $sEscSentinel = "[#ESCSEQ#]"
Local $sStringRem = StringRegExpReplace($yourstr, $sRegEsc, "^###^" & $sEscSentinel & "^###^")
ConsoleWrite("Err:" & @error & @CRLF)

Local $aResult = StringSplit($sStringRem, "^###^", $STR_ENTIRESPLIT)
ConsoleWrite("Err:" & @error & @CRLF)

If IsArray($aMatch) And IsArray($aResult) Then
    Local $iEsc = 0
    For $i = 1 To $aResult[0]
        If $aResult[$i] == $sEscSentinel Then
            $aResult[$i] = $aMatch[$iEsc]
            $iEsc += 1
        EndIf
    Next
EndIf
;---------------------------------------------------------
_ArrayDisplay($aResult)

 

Share this post


Link to post
Share on other sites
Chimp

thanks @jchd, your pattern is nearly perfect, just a little lack, it should also catch sequences where there is no parameters at all between csi (esc[) and the final character, or also if there is any combination of numbers and/or semicolons, since the absence of parameter, or numbers betwenn semicolons, is considered by ansi as the implicit value of 0. So, for example, parameter strings like the following should be considered valid escape sequences: esc[m or esc[;m or esc[3;;4m or esc[0;m or esc[;2;;3m and so on ... all valid.
Thanks a lot for your pattern


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Chimp

@Bilgus, thanks for your pattern, but testing it using the example string from @jchd post above,  it splits also or splits in a wrong way sequences that are not complete or containing spaces in between. perhaps, with a little calibration, the pattern by  jchd is OK and is able to correctly catch most of the sequences. Thank You anyway


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
jchd
4 hours ago, Bilgus said:

@Jchd have you seen that spec lol

Oh yes, I know there's much more than what I examplified. I simply followed Chimp restricted spec, simply forgot to make the numeric part optional, a gross overview. It's been many blue moons that I've typed ANSI escapes by hart.

3 hours ago, Chimp said:

perhaps, with a little calibration, the pattern by  jchd is OK and is able to correctly catch most of the sequences.

Should do what you asked for:

Local $s = "Hello, " & Chr(27) & "[ 40;31mThis is red on black " & _
            Chr(27) & "[ 47;32m And this is green on white" & _
            Chr(27) & "[ 47 ;  32   m And this is also green on white (more spaces)" & _
            Chr(27) & "[1234567890123456798Kvftio this matches the definition, albeit probably invalid ANSI escape" & _
            Chr(27) & "[ 47;32 !!!! this is not an ANSI sequence" & _
            Chr(27) & "[ z but this one is OK and final."
Local $aRes = StringRegExp($s, "(?x)" & _
                            "(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )" & _
                            "(?| \x1B (?&ANSI_Escape) | (?:[^\x1B] (?!(?&ANSI_Escape)))+ )", 3)
_ArrayDisplay($aRes, "Mixed results")

Local $sClean = StringRegExpReplace($s, "(?x) (\x1B \[ (?:\s*\d*\s*;?)* [[:alpha:]])",  "")
MsgBox(0, "Pure text", $sClean)

 

  • Like 1

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Share this post


Link to post
Share on other sites
Chimp

Thanks a lot @jchd, now it seems "perfect" .... or, at least, for the use that I have to do of it, it's more than OK.
(p.s. ...I'm playing around a simple ansi file viewer)
Many thanks to everyone


small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
Chimp

... one more question about this please,

how patterns by @jchd can be modified so that, in addition to capturing escape sequences, also some single control characters can be captured, say for example chr (10) chr (13) and chr (30)... (maybe creating a group of control codes that can be easily modified by adding or deleting some of them into the pattern?).  so for example the following string

"Hello, " & Chr(27) & "[ 40;31mThis is red on black " & chr(13) & "today is Tuesday" & chr(10) & " ... and so on"

could be transformed into the following array

[0] Hello, 
[1] esc[ 40;31m
[2] This is red on black 
[3] @CR
[4] today is Tuesday
[5] @LF
[6] ... and so on


thanks for any help

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites
mikell

Instead of walking into hazardous wild ways I would personally use a 2nd step as a workaround  :idiot:
(BTW much easier to manage, probably)

#Include <Array.au3>

Local $s = "Hello, " & Chr(27) & "[ 40;31mThis is red on black " & chr(13) & _
            Chr(27) & "[ 47;32m And this is green on white" & chr(10) & _
            Chr(27) & "[ 47 ;  32   m And this is also green on white (more spaces)" & _
            Chr(27) & "[1234567890123456798Kvftio this matches the definition, albeit probably invalid ANSI escape" & _
            Chr(27) & "[ 47;32 !!!! this is not an ANSI sequence" & _
            Chr(27) & "[ z but this one is OK and final."
Local $aRes = StringRegExp($s, "(?x)" & _
                            "(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )" & _
                            "(?| \x1B (?&ANSI_Escape) | (?:[^\x1B] (?!(?&ANSI_Escape)))+ )", 3)
;_ArrayDisplay($aRes, "Mixed results")

$s2 = _ArrayToString($aRes, "*")
$s2 = StringRegExpReplace($s2, '(?=[\r\n])', "*")
$aRes2 = StringSplit($s2, '*', 2)
_ArrayDisplay($aRes2, "Mixed results2")

;check
;Msgbox(0,"", "chr(" & asc($aRes2[3]) & ")" &@cr& "chr(" & asc($aRes2[6]) & ")" )

 

  • Like 1

Share this post


Link to post
Share on other sites
Chimp

thanks @mikell, I was thinking on how to modify that good pattern by @jchd, but you are right, this way  is easyer to manage and it do well it's job, thanks for this 2 steps version.
p.s. I see that I can add or delete other control codes to be catched (example chr(30)) by changing the list in the pattern and using the hex notation to specify exactly the wanted control codes, also, I've used chr(0) as the replace char so I can safely use the asterisc within the main text. Is ok like this or there is a better way?
Thanks again for the help.

#include <Array.au3>

Local $s = "Hello, " & Chr(27) & "[ 40;31mThis is red* on black " & Chr(30) & _
        Chr(27) & "[ 47;32m And this is green* on white" & Chr(10) & _
        Chr(27) & "[ 47 ;  32   m And this is also green on white (more spaces)" & _
        Chr(27) & "[1234567890123456798Kvftio this matches the definition, albeit probably invalid ANSI escape" & _
        Chr(27) & "[ 47;32 !!!! this is not an ANSI sequence" & _
        Chr(27) & "[ z but this one is OK and final."
Local $aRes = StringRegExp($s, "(?x)" & _
        "(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )" & _
        "(?| \x1B (?&ANSI_Escape) | (?:[^\x1B] (?!(?&ANSI_Escape)))+ )", 3)
; _ArrayDisplay($aRes, "Mixed results")

$s2 = _ArrayToString($aRes, Chr(0))
$s2 = StringRegExpReplace($s2, '(?=[\x1E\x0A])', Chr(0))
$aRes2 = StringSplit($s2, Chr(0), 2)
_ArrayDisplay($aRes2, "Mixed results2")

;check
MsgBox(0, "", "chr(" & Asc($aRes2[3]) & ")" & @CR & "chr(" & Asc($aRes2[6]) & ")")

 

 

Also, another question please,  how can I also clean the string from those control code with another pattern??

Edited by Chimp

small minds discuss people average minds discuss events great minds discuss ideas.... and use AutoIt....

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • therks
      By therks
      I'm looking for a regex genius, cus I'm stumped when it comes to assertions.
      So what I have now, is this regular expression: ([^|=]+)=([^|]+)
      It takes a string (user input) of keys=values separated by pipes (ie: "param=value|param=value") and splits them into an array.
      Example:
      $vParamData = 'example=value|fruit=apple|phrase=Hello world' $aRegEx = StringRegExp($vParamData, '([^|=]+)=([^|]+)', 3) ; Result ; [0] => example ; [1] => value ; [2] => fruit ; [3] => apple ; [4] => phrase ; [5] => Hello world So that's working fine, but I'm wondering if there's also a way I could have this capture escaped pipes instead of splitting by them.
      ie:
      $vParamData = 'pipe test=this \| is a pipe|example=value' $aRegEx = StringRegExp($vParamData, '([^|=]+)=([^|]+)', 3) ; I'm getting this: ; [0] => pipe test ; [1] => this \ ; [2] => example ; [3] => value ; But I'd like a result like this: ; [0] => pipe test ; [1] => this \| is a pipe ; [2] => example ; [3] => value Is there some pattern that would accomplish this, or am I better off parsing it some other way?
    • Chimp
      By Chimp
      Hi, this is a followup from this previous post (https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/
      I'm trying to make an ANSI file viewer. Some basic functions, even if still with some issues, let me do some early tests.
      I use a Rich Edit control as the "blackboard" where to print colored chars coming from the ANSI file (downloaded from the net), and in this "pre alpha" testing, I'm facing on a "basic" problem, that is: the chars are viewed with a wrong code page. I think that should be printed using the 437 codepage, but even trying to convert the string using the way found here (https://www.autoitscript.com/forum/topic/121847-convert-text-string-from-codepage-437-or-850-to-1252/), the result seems even worst.
      How can I display correctly the chars from the ANSI file so to produce the image, as the one shown in the InternetExplorer preview picture instead of that with altered chars shown in the rich edit control?
      Any idea on the direction to take?
      Thanks on advance.
      (to test the script, save both files in the same directory)
      #include '.\TextMode_udf.au3' #include <ie.au3> $oIe = _IECreate() ; just to see the original picture $hGUI = GUICreate("Ansi viewer", 700, 420, -1, -1, -1, $WS_EX_COMPOSITED) GUISetBkColor(0xFFFFFF) ; $Button1 = GUICtrlCreateButton("Test beastie ANSI", 590, 20, 100, 60) $Button2 = GUICtrlCreateButton("Test face_2 ANSI", 590, 100, 100, 60) $Button3 = GUICtrlCreateButton("Test flower ANSI", 590, 180, 100, 60) $Button4 = GUICtrlCreateButton("Test belinda ANSI", 590, 260, 100, 60) $Button5 = GUICtrlCreateButton("Test bambi 'text'", 590, 340, 100, 60) $Button6 = GUICtrlCreateButton("Clear screen", 15, 370, 555, 30) ; ; create a richedit _TextMode_GUICtrl_Create($hGUI, 10, 15, 80, 25, 9, "consolas") ; "Lucida console" ; "Terminal" ; "Courier new" GUISetState(@SW_SHOW, HWnd($hGUI)) ; While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop Case $Button1 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/beastie.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/beastie.ans")) _Test($sMessage) Case $Button2 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/face_2.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/face_2.ans")) _Test($sMessage) Case $Button3 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/flower.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/flower.ans")) _Test($sMessage) Case $Button4 _IENavigate($oIe,"http://artscene.textfiles.com/ansi/artwork/.png/belinda.ans.png", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/ansi/artwork/belinda.ans")) _Test($sMessage) Case $Button5 _IENavigate($oIe,"http://artscene.textfiles.com/vt100/bambi.vt", 0) $sMessage = BinaryToString(InetRead("http://artscene.textfiles.com/vt100/bambi.vt")) _Test($sMessage) Case $Button6 _TextMode_CLS() EndSwitch WEnd _IEQuit($oIe) Exit ; Func _Test($sMessage) ; $sMessage = _StringToCodepage($sMessage, 437) _TextMode_Print($sMessage); parse the ANSI string and print result to the RichEdit EndFunc ;==>_Test ; https://www.autoitscript.com/forum/topic/121847-convert-text-string-from-codepage-437-or-850-to-1252/ Func _StringToCodepage($ansi, $codepage) Local $struct = DllStructCreate("byte[" & StringLen($ansi) * 2 + 4 & "]") ;platz für UTF16 $string = _WinAPI_MultiByteToWideCharEx($ansi, DllStructGetPtr($struct), Number($codepage), $MB_PRECOMPOSED) ; $MB_USEGLYPHCHARS) ;Ansi-String in Codepage umwandeln Return BinaryToString(DllStructGetData($struct, 1), 2) EndFunc ;==>_StringToCodepage save this as "TextMode_udf.au3" (pre alpha code)
      ; the following include is by @melba23 ; get it here -> https://www.autoitscript.com/forum/topic/114034-stringsize-m23-new-version-16-aug-11/ ; #include <stringsize.au3> ; for the moment is not used here since I'm using a fixed width control just for testing #include <array.au3> #include <GuiRichEdit.au3> #include <GUIConstants.au3> ; ===== !! PRE ALPHA CODE FOR EARLY TESTING !! ===== ; 'paper' dimension in chars (columns and lines) Global $iHwidth = 80 ; width of screen (nr. of chars per line) Global $iVheight = 24 ; height of screen (nr. of lines) ; Font and size (a monospaced font is MANDATORY!) Global $iFontSize = 12, $sFontName = "Consolas" ; "Terminal" ; "Perfect DOS VGA 437 Win" ; "Courier New" ; "Lucida Sans Typewriter" ; "Lucida Console" ; Global $iTabStop = 8 ; Horizontal tab stops (Historically tab stops where every 8th character) Global $iCharSet = 2 ; see --> _GUICtrlRichEdit_SetFont() #cs the character set - one of: $ANSI_CHARSET - 0 $BALTIC_CHARSET - 186 $CHINESEBIG5_CHARSET - 136 $DEFAULT_CHARSET - 1 $EASTEUROPE_CHARSET - 238 $GB2312_CHARSET - 134 $GREEK_CHARSET - 161 $HANGEUL_CHARSET - 129 $MAC_CHARSET - 77 $OEM_CHARSET - 255 $RUSSIAN_CHARSET - 204 $SHIFTJIS_CHARSET - 128 $SYMBOL_CHARSET - 2 $TURKISH_CHARSET - 162 $VIETNAMESE_CHARSET - 163 #ce ; ; the screen text buffer Global $sBuffer = "" Global $_hVintageGui, $hScreen[2] ; initialize cursor position Global $iCursorPosX = 1 ; horizontal position Global $iCursorPosY = 1 ; vertical position Global $iCursorPushX = $iCursorPosX ; Save X (for a later pull) Global $iCursorPushY = $iCursorPosY ; Save Y (for a later pull) Global $iVisibleLayer = 0 ; there are 2 screens (0 and 1) ; possible text modes. ; To set a text mode use _TextMode_Mode($mode). Without a parameter it returns current mode Global Enum $Normal, $Inverse, $Blink, $Flash ; Text attributes (to be set each for himself True/False) Global $Bold = False Global $Italic = False Global $Underline = False Global $aAttribute[2] = ['-', '+'] ; False = - True = + ; Color names Global Enum $Black, $Red, $Green, $Yellow, $Blue, $Magenta, $Cyan, $White, _ $BrightBlack, $BrightRed, $BrightGreen, $BrightYellow, $BrightBlue, $BrightMagenta, $BrightCyan, $BrightWhite ; Set ANSI color values (GRB color values from here: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors) Global $aColor[16] $aColor[$Black] = 0x000000 ; 00 = Black bk .......0 $aColor[$Red] = 0x000080 ; 01 = Red rd .....128 $aColor[$Green] = 0x008000 ; 02 = Green gn ...32768 $aColor[$Yellow] = 0x008080 ; 03 = Yellow yl ...32896 $aColor[$Blue] = 0x800000 ; 04 = Blue bu .8388608 $aColor[$Magenta] = 0x800080 ; 05 = Magenta mg .8388736 $aColor[$Cyan] = 0x808000 ; 06 = Cyan cy .8421376 $aColor[$White] = 0xC0C0C0 ; 07 = White wt 12632256 $aColor[$BrightBlack] = 0x808080 ; 08 = Bright Black BK .8421504 $aColor[$BrightRed] = 0x0000FF ; 09 = Bright Red RD .....255 $aColor[$BrightGreen] = 0x00FF00 ; 10 = Bright Green GN ...65280 $aColor[$BrightYellow] = 0x00FFFF ; 11 = Bright Yellow YE ...65535 $aColor[$BrightBlue] = 0xFF0000 ; 12 = Bright Blue BU 16711680 $aColor[$BrightMagenta] = 0xFF00FF ; 13 = Bright Magenta MG 16711935 $aColor[$BrightCyan] = 0xFFFF00 ; 14 = Bright Cyan CY 16776960 $aColor[$BrightWhite] = 0xFFFFFF ; 15 = Bright White WT 16777215 ; default text colors Global Static $iDefaultForeground = $BrightWhite Global Static $iDefaultBackground = $Black Global $iActiveFGColor = $iDefaultForeground Global $iActiveBGColor = $iDefaultBackground ; ensure creation of only one TextMode 'control' Global $bControlExists = False HotKeySet("{ESC}", "_EndANSI") ; press 'esc' to end ; create a control to be placed on a parent GUI Func _TextMode_GUICtrl_Create($hWnd, $iLeft = 0, $iTop = 0, $i_Hwidth = $iHwidth, $i_Vheight = $iVheight, $i_FontSize = $iFontSize, $s_FontName = $sFontName, $i_DefaultForeground = $iDefaultForeground, $i_DefaultBackground = $iDefaultBackground) If $bControlExists = True Then Return ; if default values are changed then set also global variables accordingly $iHwidth = $i_Hwidth $iVheight = $i_Vheight $sFontName = $s_FontName $iFontSize = $i_FontSize $iDefaultForeground = $i_DefaultForeground $iDefaultBackground = $i_DefaultBackground ; fill the buffer $sBuffer = _StringReplay(_StringReplay(" ", $i_Hwidth) & @CRLF, $i_Vheight - 1) & _StringReplay(" ", $i_Hwidth) ; a string of width * height blank spaces + @crlf #cs ; determine the size of the screen according to the font parameters (by @Melba23) Local $aWinDim = _StringSize($sBuffer, $i_FontSize, 400, 0, $s_FontName) $aWinDim[2] += _StringSize(" ", $i_FontSize, 400, 0, $s_FontName)[2] Local $iWidth = $aWinDim[2], $iHeight = $aWinDim[3] ; Screen dimensions #ce Local $iWidth = 567, $iHeight = 354 ; Screen dimensions (fixed here just for the test) ; a transparent layer above the rich edit to protect it from clicks and to allow dragging of the GUI Local $hGlass = GUICtrlCreateLabel("", $iLeft, $iTop, $iWidth, $iHeight, -1, $GUI_WS_EX_PARENTDRAG) GUICtrlSetBkColor(-1, $GUI_BKCOLOR_TRANSPARENT) ; This is like a glass over the underlying RichEdit GUICtrlSetCursor(-1, 2) ; Cursor is an arrow (instead of the default I-beam) $hScreen[0] = HWnd(_GUICtrlRichEdit_Create($hWnd, "", $iLeft, $iTop, $iWidth, $iHeight, BitXOR($ES_READONLY, $ES_MULTILINE))) ; DllCall('user32.dll', 'uint_ptr', 'SetTimer', 'hwnd', 0, 'uint_ptr', 0, 'uint', 500, 'ptr', DllCallbackGetPtr(DllCallbackRegister('__SwitchScreen', 'none', 'hwnd;uint;uint_ptr;dword'))) _TextMode_CLS() ; Initialize and clear the screen $bControlExists = True Return $hScreen EndFunc ;==>_TextMode_GUICtrl_Create ; From Htab Vtab (1 based) to absolute within the screen buffer Func __GetAbsPos($iHtab = 1, $iVtab = 1, $iScreenWidth = $iHwidth) Return ($iVtab - 1) * ($iScreenWidth + 1) + $iHtab EndFunc ;==>__GetAbsPos ; From Absolute To Htab Vtab (1 based) Func __GetTabsPos($iAbsolutePos = 1, $iScreenWidth = $iHwidth) Local $aXY[2] $aXY[0] = Mod($iAbsolutePos - 1, $iScreenWidth) + 1 ; Horizontal position within the Screen (column) $iHtab $aXY[1] = Int(($iAbsolutePos - 1) / $iScreenWidth) + 1 ; Vertical position within the Screen (row) $iVtab Return $aXY EndFunc ;==>__GetTabsPos ; don't show drawing activity (draw behind the shenes) Func _TextMode_PauseRedraw() _GUICtrlRichEdit_PauseRedraw($hScreen[0]) EndFunc ;==>_TextMode_PauseRedraw ; show what's been drawn Func _TextMode_ResumeRedraw() _GUICtrlRichEdit_ResumeRedraw($hScreen[0]) EndFunc ;==>_TextMode_ResumeRedraw ; #FUNCTION# ==================================================================================================================== ; Name ..........: _TextMode_Print ; Description ...: Main printing function ; Syntax ........: _TextMode_Print([$sString = ""[, $iHtab = $iCursorPosX[, $iVtab = $iCursorPosY[, $iForegroundColor = $iActiveFGColor[, ; $iBackgroundColor = $iActiveBGColor]]]]]) ; Parameters ....: $sString - [optional] a string value. Default is "". ; $iHtab - [optional] column where to start printing ; $iVtab - [optional] row where to start printnting ; $iForegroundColor - [optional] wanted foreground color ; $iBackgroundColor - [optional] Wanted bckground color ; =============================================================================================================================== Func _TextMode_Print($sString = "", $iHtab = $iCursorPosX, $iVtab = $iCursorPosY, $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) If $iHtab = Default Then $iHtab = $iCursorPosX If $iVtab = Default Then $iVtab = $iCursorPosY ; Local $aString = __StringSplitKeepTokens($sString) ; break the string to find the control characters Local $iStartingHtab = $iHtab ; Local $iActiveFGColor = $iForegroundColor ; Local $iActiveBGColor = $iBackgroundColor Local $sANSI_Escape Local $aParameters[1] ; split string on ansi escape sequences and control codes (if any) ; ---------------------------------------------------------------- ; Main RegExp pattern by @jchd (Thanks to @jchd) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1386039 ; pattern also modified by @mikell (Thanks to @mikell) https://www.autoitscript.com/forum/topic/192953-regexp-and-ansi-escape-sequences/?do=findComment&comment=1387160 Local $aStringChunks = StringRegExp($sString, "(?x)(?(DEFINE) (?<ANSI_Escape> \[ (?:\s*\d*\s*;?)* [[:alpha:]]) )(?| \x1B(?&ANSI_Escape) | [\x01-\x1A\x1C-\x1F] | \x1B(?!(?&ANSI_Escape)) | (?:[^\x01-\x1F] (?!(?&ANSI_Escape)))+ )", 3) ; _ArrayDisplay($aStringChunks, "Debug") For $iChunk = 0 To UBound($aStringChunks) - 1 ; check presence of escape sequences or control chars $sANSI_Escape = StringReplace($aStringChunks[$iChunk], " ", "") ; clean unneeded (and disturbing)spaces If StringLeft($sANSI_Escape, 2) = Chr(27) & "[" Then ; it is a CSI (Control Sequence Introducer) ; ConsoleWrite("Debug: CSI -> " & $sANSI_Escape & @CRLF) ; get ansi escape sequence parameters $aParameters = StringSplit(StringMid(StringTrimRight($sANSI_Escape, 1), 3), ";") ; extract the parameters of this sequence $aParameters[0] = StringRight($sANSI_Escape, 1) ; gat the final character (put it in [0]) ; _ArrayDisplay($aParameters, "Debug") ; ; ANSI Escape squence interpreter ; ------------------------------- Select Case $aParameters[0] == "a" ; HPR Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "d" ; VPA Move cursor to the indicated row, current column. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "e" ; VPR Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "f" ; HVP Move cursor to the indicated row, column. ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "g" ; TBC Without parameter: clear tab stop at current position. ; ? Case $aParameters[0] == "h" ; SM Set Mode ; ? Case $aParameters[0] == "l" ; RM Reset Mode ; ? Case $aParameters[0] == "m" ; SGR Set attributes. ; _ArrayDisplay($aParameters,"Debug") For $iParam = 1 To UBound($aParameters) - 1 Switch Number($aParameters[$iParam]) Case 0 ; reset all attributes to their defaults _TextMode_SetDefaultColors() _TextMode_SetMode($Normal) $Bold = False $Italic = False $Underline = False Case 1 ; set bold $Bold = True Case 4 ; set underscore $Underline = True Case 5 ; set blink _TextMode_SetMode($Blink) Case 7 ; set reverse video _TextMode_SetMode($Inverse) Case 8 ; concealed (foreground becomes background) _TextMode_SetMode($Inverse) Case 22 ; bold off $Bold = False Case 24 ; underline off $Underline = False Case 25 ; blink off _TextMode_SetMode($Normal) Case 27 ; reverse video off _TextMode_SetMode($Normal) Case 28 ; concealed off _TextMode_SetMode($Normal) Case 30 To 37 ; set foreground color $iForegroundColor = _TextMode_SetActiveForeColor(Number($aParameters[$iParam]) - 30) Case 38 ; set default foreground color ; 38;2;# foreground based on index (0-255) ; 38;5;#;#;# foreground based on RGB Case 39 ; set default foreground (using current intensity) Case 40 To 47 ; set background color $iBackgroundColor = _TextMode_SetActiveBackColor(Number($aParameters[$iParam]) - 40) Case 48 ; 48;2;# background based on index (0-255) ; 48;5;#;#;# background based on RGB Case 49 ; set default background (using current intensity) Case 90 To 97 ; set foreground bright color $iForegroundColor = _TextMode_SetActiveForeColor(Number($aParameters[$iParam]) - 82) Case 100 To 107 ; ; set background bright color $iBackgroundColor = _TextMode_SetActiveBackColor(Number($aParameters[$iParam]) - 92) EndSwitch Next Case $aParameters[0] == "n" ; DSR Status report ; ? Case $aParameters[0] == "q" ; DECLL Set keyboard LEDs. ; ESC [ 0 q: clear all LEDs ; ESC [ 1 q: set Scroll Lock LED ; ESC [ 2 q: set Num Lock LED ; ESC [ 3 q: set Caps Lock LED Case $aParameters[0] == "r" ; DECSTBM Set scrolling region; parameters are top and bottom row. Case $aParameters[0] == "s" ; ? Save cursor location. _PushCursor() Case $aParameters[0] == "u" ; ? Restore cursor location. _PullCursor() $iHtab = $iCursorPosX $iVtab = $iCursorPosY Case $aParameters[0] == "`" ; HPA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "@" ; ICH Insert the indicated # of blank characters. Case $aParameters[0] == "A" ; CUU Move cursor up the indicated # of rows. ; ConsoleWrite("Debug: " & Number($aParameters[1]) - ($aParameters[1] = 0) & @CRLF) $iVtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "B" ; CUD Move cursor down the indicated # of rows. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab Case $aParameters[0] == "C" ; CUF Move cursor right the indicated # of columns. $iHtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "D" ; CUB Move cursor left the indicated # of columns. $iHtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "E" ; CNL Move cursor down the indicated # of rows, to column 1. $iVtab += Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] == "F" ; CPL Move cursor up the indicated # of rows, to column 1. $iVtab -= Number($aParameters[1]) - ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] == "G" ; CHA Move cursor to indicated column in current row. $iHtab = Number($aParameters[1]) $iCursorPosX = $iHtab Case $aParameters[0] == "H" ; CUP Move cursor to the indicated row, column (origin at 1,1). ReDim $aParameters[3] ; mandatory 2 parameters $iVtab = Number($aParameters[1]) + ($aParameters[1] = 0) $iCursorPosY = $iVtab $iHtab = Number($aParameters[2]) + ($aParameters[2] = 0) $iCursorPosX = $iHtab Case $aParameters[0] == "J" ; ED Erase display (default: from cursor to end of display). ReDim $aParameters[2] ; mandatory 1 parameters Switch Number($aParameters[1]) Case 0 ; Pn=0: erases from active position to end of display. __Sub_Print(_StringReplay(" ", $iHwidth - $iHtab + 1), $iHtab, $iVtab, $iDefaultForeground, $iDefaultBackground) If $iVtab < $iVheight Then For $y = $iVtab + 1 To $iVheight __Sub_Print(_StringReplay(" ", $iHwidth), 1, $y, $iDefaultForeground, $iDefaultBackground) Next EndIf Case 1 ; Pn=1: erases from the beginning of display to active position. __Sub_Print(_StringReplay(" ", $iHtab), 1, $iVtab, $iDefaultForeground, $iDefaultBackground) If $iVtab > 1 Then For $y = 1 To $iVtab - 1 __Sub_Print(_StringReplay(" ", $iHwidth), 1, $y, $iDefaultForeground, $iDefaultBackground) Next EndIf Case 2 ; Pn=2: erases entire display and move cursor to the top-left. _TextMode_CLS() $iHtab = 1 $iVtab = 1 EndSwitch Case $aParameters[0] == "K" ; EL Erase line (default: from cursor to end of line). __Sub_Print(_StringReplay(" ", $iHwidth - $iHtab + 1), $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) Case $aParameters[0] == "L" ; IL Insert the indicated # of blank lines. Case $aParameters[0] == "M" ; DL Delete the indicated # of lines. Case $aParameters[0] == "P" ; DCH Delete the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) Case $aParameters[0] == "X" ; ECH Erase the indicated # of characters on current line. __Sub_Print(_StringReplay(" ", $aParameters[1]), $iHtab, $iVtab, $iDefaultForeground, $iDefaultBackground) EndSelect ; ; is it a single Control character ? (http://jkorpela.fi/chars/c0.html) ElseIf StringLen($sANSI_Escape) = 1 And (AscW($sANSI_Escape) >= 0 And AscW($sANSI_Escape) <= 0x1F) Then ; and 1 = 2 ; ConsoleWrite("Debug: ctrl -> " & @TAB & "[" & Ascw($sANSI_Escape) & "]" & @TAB & "[" & Asc($sANSI_Escape) & "]" & @TAB & "<-----------------------------" & @CRLF) ; control character interpreter ; --------------------------------------------------------------------------------------- $aParameters[0] = $sANSI_Escape Select Case $aParameters[0] = Chr(7) ; Bell, rings the bell Beep(900, 150) Case $aParameters[0] = Chr(8) ; Backspace <-- $iHtab -= 1 $iCursorPosX = $iHtab Case $aParameters[0] = Chr(9) ; Horizontal tab ; (Historically tab stops were every 8th character) If $iHtab >= 0 Then $iHtab = $iHtab + (Mod($iHtab, $iTabStop) * -1) + $iTabStop Else $iHtab = $iHtab + (Mod(Abs($iHtab) - 1, $iTabStop) + 1) EndIf $iCursorPosX = $iHtab Case $aParameters[0] = Chr(10) ; Line Feed @LF (move cursor down by 1 line) $iVtab += 1 $iCursorPosY = $iVtab Case $aParameters[0] = Chr(11) ; Vertical tab (move cusros up by 1 line) $iVtab -= 1 $iCursorPosY = $iVtab Case $aParameters[0] = Chr(12) ; Form Feed ; Case $aParameters[0] = Chr(13) ; Carriage Return @CR (move cursor to the beginning of this line) $iHtab = 1 $iCursorPosX = $iHtab Case $aParameters[0] = Chr(24) ; backspace with deletion (Cancel) $iHtab -= 1 __Sub_Print(" ", $iHtab, $iVtab, $iActiveFGColor, $iActiveBGColor) $iCursorPosX = $iHtab Case $aParameters[0] = Chr(30) ; LF + a partial CR (Carriage Return stops below previous HTab) ; (custom private) $iVtab += 1 $iHtab = $iStartingHtab $iCursorPosX = $iHtab $iCursorPosY = $iVtab Case $aParameters[0] = Chr(31) ; move cursor to the right by 1 char --> ; ConsoleWrite(".") $iHtab += 1 $iCursorPosX = $iHtab EndSelect Else ; print the text ; ConsoleWrite("Debug: FG=" & $iActiveFGColor & @TAB & "BG=" & $iActiveBGColor & @CRLF) ; $aStringChunks[$iChunk] = StringReplace(StringStripCR(_StringToCodepage($aStringChunks[$iChunk], 437)), @LF, "") __Sub_Print(StringReplace($aStringChunks[$iChunk], ChrW(0), ""), $iHtab, $iVtab, $iForegroundColor, $iBackgroundColor) $iHtab = $iCursorPosX $iVtab = $iCursorPosY EndIf Next EndFunc ;==>_TextMode_Print ; keep only the string portion that will fall into the the screen (parts outside the screen will be discarded) Func __Sub_Print($sString = "", $iHtab = $iCursorPosX, $iVtab = $iCursorPosY, $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) Local $iStringFullLen = StringLen($sString) Local $iStringLen = $iStringFullLen If Not $iStringLen Then Return ; no string to print Local $iStringEnd = $iHtab + $iStringLen - 1 $iCursorPosX = $iHtab + $iStringLen $iCursorPosY = $iVtab If _ ; check if all the string falls outside the printable area $iHtab > $iHwidth Or _ ; over the right edge $iVtab > $iVheight Or _ ; below the bottom $iVtab < 1 Or _ ; over the top edges $iStringEnd < 1 _ ; over the left edge Then Return ; adjust string if only a part has to be Printed If $iHtab < 1 Then ; remove the part outside on the left $sString = StringRight($sString, $iStringEnd) $iStringLen = StringLen($sString) $iHtab = 1 EndIf If $iStringEnd > $iHwidth Then ; removes the exceeding part on the right $sString = StringTrimRight($sString, $iStringEnd - $iHwidth) $iStringLen = StringLen($sString) EndIf Local $iAnchor = __GetAbsPos($iHtab, $iVtab) - 1 Local $iActive = $iAnchor + $iStringLen Switch _TextMode_Mode() Case $Normal ; print normal text on both layers __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case $Inverse ; switch foreground and background colors and print on both layers __PokeText(0, $sString, $iAnchor, $iActive, $iBackgroundColor, $iForegroundColor) Case $Blink ; to be continued .... __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case $Flash ; to be continued .... __PokeText(0, $sString, $iAnchor, $iActive, $iForegroundColor, $iBackgroundColor) Case Else EndSwitch EndFunc ;==>__Sub_Print ; Place string on the "screen" buffer Func __PokeText($iLayer, $sString, $iAnchor, $iActive, $iForeColor, $iBackColor) ; select the part of the screen buffer to be replaced with the incoming $sString _GUICtrlRichEdit_SetSel($hScreen[$iLayer], $iAnchor, $iActive, True) ; set styles for the incoming text _GUICtrlRichEdit_SetFont($hScreen[$iLayer], $iFontSize, $sFontName, $iCharSet) _GUICtrlRichEdit_SetCharColor($hScreen[$iLayer], __PeekColor($iForeColor)) _GUICtrlRichEdit_SetCharBkColor($hScreen[$iLayer], __PeekColor($iBackColor)) ; set or unset bold, italic, underline according if the rispective variable is set to true or false _GUICtrlRichEdit_SetCharAttributes($hScreen[$iLayer], $aAttribute[$Bold] & 'bo' & $aAttribute[$Italic] & 'it' & $aAttribute[$Underline] & 'un') ; place the text on the screen _GUICtrlRichEdit_ReplaceText($hScreen[$iLayer], $sString, False) _GUICtrlRichEdit_Deselect($hScreen[$iLayer]) EndFunc ;==>__PokeText Func _PushCursor($sAction = "Push") Local Static $iCursorPushX = $iCursorPosX Local Static $iCursorPushY = $iCursorPosY If $sAction = "Push" Then $iCursorPushX = $iCursorPosX $iCursorPushY = $iCursorPosY EndIf Local $aXY[2] = [$iCursorPushX, $iCursorPushY] Return $aXY EndFunc ;==>_PushCursor Func _PullCursor() Local $aXY = _PushCursor("Pull") $iCursorPosX = $aXY[0] $iCursorPosY = $aXY[1] EndFunc ;==>_PullCursor ; if you pass a number 0-15 it returns a predefined color from the $aColor[] array. ; if the number is > 15 and <= 0xFFFFFF it returns the same number, while if the passed ; number is out of range it return 0 ($Black)and sets @error Func __PeekColor($iColor) $iColor = Number($iColor) If $iColor >= 0 And $iColor < UBound($aColor) Then Return $aColor[$iColor] ; predefined colors ElseIf $iColor >= UBound($aColor) And $iColor <= 0xFFFFFF Then Return $iColor ; value is <= 0xFFFFFF Else Return SetError(1, 0, 0) ; if out of range return Black and set error EndIf EndFunc ;==>__PeekColor ; clear the screen (fill screen buffer with spaces) ; (for 'crazy' effects you could also select another char instead of the space and custom colors) Func _TextMode_CLS($sFillChr = " ", $iForegroundColor = $iActiveFGColor, $iBackgroundColor = $iActiveBGColor) ; clear the screen ; fill screen with white spaces (screen buffer) _GUICtrlRichEdit_SetText($hScreen[0], _StringReplay(_StringReplay($sFillChr, $iHwidth) & @CRLF, $iVheight - 1) & _StringReplay($sFillChr, $iHwidth)) _GUICtrlRichEdit_SetSel($hScreen[0], 0, -1, True) ; select whole screen ; set parameters _GUICtrlRichEdit_SetFont($hScreen[0], $iFontSize, $sFontName, $iCharSet) ; Set Font _GUICtrlRichEdit_SetCharColor($hScreen[0], __PeekColor($iForegroundColor)) ; Set Foreground default color _GUICtrlRichEdit_SetCharBkColor($hScreen[0], __PeekColor($iBackgroundColor)) ; Set Background default color _GUICtrlRichEdit_SetSel($hScreen[0], 0, 0, False) ; set cursor to home $iCursorPosX = 1 $iCursorPosY = 1 EndFunc ;==>_TextMode_CLS Func _TextMode_SetDefaultColors($iForeColor = $iDefaultForeground, $iBackColor = $iDefaultBackground) If $iForeColor = Default Then $iForeColor = $iDefaultForeground If $iForeColor < $Black Or $iForeColor > $BrightWhite Or $iForeColor = "" Then $iForeColor = $iActiveFGColor If $iBackColor = Default Then $iBackColor = $iDefaultBackground If $iBackColor < $Black Or $iBackColor > $BrightWhite Or $iBackColor = "" Then $iBackColor = $iActiveBGColor $iActiveFGColor = $iForeColor $iActiveBGColor = $iBackColor Local $aDefaultColors = [$iActiveFGColor, $iActiveBGColor] Return $aDefaultColors EndFunc ;==>_TextMode_SetDefaultColors Func _TextMode_SetActiveForeColor($iForeColor = $iActiveFGColor) If $iForeColor = Default Then $iForeColor = $iDefaultForeground If $iForeColor < $Black Or $iForeColor > $BrightWhite Then $iForeColor = $iActiveFGColor $iActiveFGColor = $iForeColor Return $iActiveFGColor EndFunc ;==>_TextMode_SetActiveForeColor Func _TextMode_SetActiveBackColor($iBackColor = $iActiveBGColor) If $iBackColor = Default Then $iBackColor = $iDefaultBackground If $iBackColor < $Black Or $iBackColor > $BrightWhite Then $iBackColor = $iActiveBGColor $iActiveBGColor = $iBackColor Return $iActiveBGColor EndFunc ;==>_TextMode_SetActiveBackColor ; Get / Set active TextMode effect Func _TextMode_Mode($iMode = -1) Local Static $iTextMode If $iMode >= $Normal And $iMode <= $Flash Then $iTextMode = $iMode Return $iTextMode EndFunc ;==>_TextMode_Mode ; set Normal or Inverse or Blink or Flash Func _TextMode_SetMode($iMode = $Normal) If $iMode >= $Normal And $iMode <= $Flash Then Return _TextMode_Mode($iMode) Else Return _TextMode_Mode() EndIf EndFunc ;==>_TextMode_SetMode ; check if is within color ranges Func _IsRGB($iColor) Return $iColor >= 0x000000 And $iColor <= 0xFFFFFF EndFunc ;==>_IsRGB ; move the TextMode GUI to Func _TextMode_GUIMoveTo($iX = 5, $iY = 5, $_hGUI = $_hVintageGui) If IsHWnd($_hGUI) Then WinMove($_hGUI, "", $iX, $iY) EndFunc ;==>_TextMode_GUIMoveTo Func _EndANSI() _GUICtrlRichEdit_Destroy($hScreen[0]) Exit EndFunc ;==>_EndANSI ; returns one or more chars replicated n times ; Example: ConsoleWrite(_StringReplay('*', 5) & @CRLF) Func _StringReplay($sChars = "", $iRepeats = 0) $sChars = String($sChars) $iRepeats = Int(Abs(Number($iRepeats))) Return StringReplace(StringFormat('%' & $iRepeats & 's', ""), " ", $sChars) EndFunc ;==>_StringReplay  
    • ur
      By ur
      I am trying to identify the window based on the window title and text.
      The title will be the "erwin DM - filename"

      It is working till date, but some operating systems our application is displaying window as "erwin DM - [filename]"
       
      I tried  "erwin DM - *filename*" But this regular expression is not working.
      Any suggestion?
       
      $sModelFile = "C:\Users\Administrator\Documents\My Models\eMovies.erwin" $wdModel = _WinWaitActivate1("erwin DM - "&FileNameOnly($sModelFile),"") Func _WinWaitActivate1($title,$text,$timeout=0);Will Return the window Handler Logging("Waiting for "&$title&":"&$text) $dHandle = WinWait($title,$text,$timeout) if not ($dHandle = 0) then If Not WinActive($title,$text) Then WinActivate($title,$text) return WinWaitActive($title,$text,$timeout) Else Logging("Timeout occured while waiting for the window...") Exit EndIf EndFunc Func FileNameOnly($sFilePath) Local $sDrive = "", $sDir = "", $sFileName = "", $sExtension = "" Local $aPathSplit = _PathSplit($sFilePath, $sDrive, $sDir, $sFileName, $sExtension) ;_ArrayDisplay($aPathSplit, "_PathSplit of " & @ScriptFullPath) return $sFileName EndFunc  
    • nend
      By nend
      This is a program that I made to help my self learn better regular expressions.
      There are a lot of other programs/website with the similar functions.
      But the main advantage of this program is that you don't have to click a button after every changes.
      The program detected changes and react on it.
      Function:
      Match Match of arrays Match and replace Load source data from website Load source data from a website with GET/POST Load text data from file Clear fields Export and Import settings (you can finish the expression a other time, just export/import it) Cheat sheet Generate AutoIt code The source code is not difficult and I think most user will understand it.
      In the zip file there are 2 export files (POST and a reg back example), you can drag and drop these files on the gui to import them.
      Download Regex Toolkit here Regex toolkit.zip
      EDIT: Updated to version V1.2.0
      Changes are:
      Expand and collapse of the cheat sheet (Thanks to Melba23 for the Guiextender UDF) Usefull regular expressions websites links included in the prgram Text data update time EDIT: Updated to version V1.3.0
      Changes are:
       Automatic generate AutoIt code  Icons on the tab  Few minor bug fixes EDIT: Updated to version V1.4.0
      Changes are:
      Link to AutoIt regex helpfile If the regular expression has a error than the text becomes red Option Offset with Match and array of Matches Option Count with Match and replace Some small minor bug fixed
    • nikink
      By nikink
      Hi all, it's been a while since I last used regular expressions and I find myself out of time to experiment with this particular issue, so I throw myself upon your mercy and expertise.
      I am looking to create a function that will say whether or not a supplied string is a valid UUID or not.
      Local $sTestF = '4C4C4544-004A-4C10-8054-B7C04F46343' Local $sTestT = '4C4C4544-004A-4C10-8054-B7C04F463432' ConsoleWrite('False = ' & _IsValidUUID($sTestF) & @CRLF) ConsoleWrite('True = ' & _IsValidUUID($sTestT) & @CRLF) Func _IsValidUUID($sUUID) ;[\p{XDigit}]{8}-[\p{XDigit}]{4}-[34][\p{XDigit}]{3}-[89ab][\p{XDigit}]{3}-[\p{XDigit}]{12} ; Test UUID = '4C4C4544-004A-4C10-8054-B7C04F463432' Local $sRegExp = '([:xdigit:]){8}\-([:xdigit:]){4}\-([34])([:xdigit:]){3}\-([89ab])([:xdigit:]){3}\-([:xdigit:]){12}' ConsoleWrite(StringRegExp($sUUID, $sRegExp) & @CRLF) Local $Result = StringRegExp($sUUID, $sRegExp) ConsoleWrite($Result & @CRLF) If @error Then ConsoleWrite('Error: [' & @error & ']' & @CRLF) Return 'False' Else ConsoleWrite('Error2: [' & @error & ']' & @CRLF) Return 'True' EndIf EndFunc In the line under the Function call, you'll see the regex I found to do this from a google search. That was my starting point, and I'm trying to get it to work in Au3 and failing miserably.
      $sTestF is a known invalid String
      $sTestT is a known valid String
      Everything I've tried so far has produced the same results for both.
      Any help you could provide me is greatly appreciated. Thanks for your time!
×