Test string for <, > or %

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Message
Author
Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Test string for <, > or %

#1 Post by Jer » 30 Nov 2015 22:02

I am working on a utility that incorporates Carlos' color function, and have a problem
with special characters that may appear in the text displayed on a uniform color panel.

The problem: when the text contains %, >, or %, either one or several, my string of text
padded with leading and trailing blanks is short 1 character. The color panel is therefore short by 1 character.
I check the length of the string of text, calculate the spaces right and left for centering, add 2 columns
for left and right margins, then feed the variables to the color function:
Call :color %colors% "%spacesLEFT%%str%%spacesRIGHT%"

I would like to be able to test the text for <, > or % and add an additional blank space to
the string if any of the characters are found. Here is my test code to find the characters:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

Set "txt=> Game Over <"
Call:isSpecChar "%txt%"

Set "txt=You scored 100%%%%."
Call :isSpecChar "%txt%"

Set "txt=Goodbye."
Call :isSpecChar "%txt%"

endlocal & exit /b


:isSpecChar
setlocal DisableDelayedExpansion
rem check for chars % < and >

Set "specialChar=FALSE"
Set "STRING=%~1"

Set "STRING=%STRING:<=%"

If Not ."%STRING%".==.%1%. Set "specialChar=TRUE"& GoTo:endISC

Set "STRING=%STRING:>=%"
If Not ."%STRING%".==.%1%. Set "specialChar=TRUE"& GoTo:endISC

Set "STRING=%STRING:^%=%"
If Not ."%STRING%".==.%1%. Set "specialChar=TRUE"

:endISC
echo was special character found? !specialChar!

endlocal & exit /b 

and the error:
C:\Temp\>If Not ."> Game Over ".==."> Game Over <"endISC

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Test string for <, > or %

#2 Post by jeb » 01 Dec 2015 02:54

Hi Jer,

the main problems are in the lines like

Code: Select all

If Not ."%STRING%".==.%1%. Set ...

The syntax is wrong, it should only be %1, and more important working here with %1 at all will only produce problems.
It's better to work only with the %string% variable

Code: Select all

:isSpecChar
setlocal DisableDelayedExpansion
rem check for chars % < and >

Set "specialChar=FALSE"
Set "STRING=%~1"

If "%STRING%" NEQ == "%STRING:<=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:>=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:&=%" Set "specialChar=TRUE"& GoTo:endISC
...

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: Test string for <, > or %

#3 Post by Jer » 02 Dec 2015 01:40

Thanks Jeb. I was not aware of the "NEQ ==" coding so now I have that for my "tool-belt".
.%1%. happens when a person stays up too late. :(
It turns out that I need to check for the ampersand; how wise you were to include that character
for my color canvas project.

The solution works in my project. The color lines are displayed with the background color having a set width.
When the line of text includes one or more of the 4 special characters, 2 blank spaces are added to even out the canvas,
and the background color display has the correct width even if the text line has several different special characters.

Lines from a text file are displayed, including blanks. The next stage in development is to try to speed it up,
possibly by using fewer temporary files. Here is the batch file that demonstrates the special character-checking code.

edit 12/2/2015: After testing my canvas code the next day, adding 2 spaces for the ampersand caused the width of
the colored line to be 2 characters too wide. More research is needed--maybe a way to get a substring of the whole line,
except special characters in the text are a problem when doing that.

Code: Select all

@echo off
setlocal EnableDelayedExpansion

>"test.txt" (
   Set "str=> Game Over <"& Echo !str!
   Set "str=Greetings & Salutations Mickey"& Echo !str!
   Set "str=Your playing time was -->  23 minutes 14 seconds"& Echo !str!
   Set "str=You scored 1,000 points."& Echo !str!
   Set "str=That's 100%%."& Echo !str!
   Set "str=Keep this up and your name may be added to"& Echo !str!
   Set "str=the Top Players of the Month List"& Echo !str!
   Set "str=Insert Five Quarters to Play Again<<<"& Echo !str!
)

Echo(& Echo Search a file for greater-than, less-than, ampersand
Echo and percent symbols in these lines:
Echo(& Type test.txt
Echo(& Echo search results:& Echo(

For /F "delims=" %%a In (test.txt) Do (
   Echo "%%a">tmp.txt
   Call :isSpecialChar "%%a" charFound
   If "!charFound!"=="TRUE" Echo special character found: "%%a"  !charFound!
)

If EXIST test.txt DEL test.txt
If EXIST tmp.txt DEL tmp.txt

endlocal & exit /b


:isSpecialChar
setlocal EnableDelayedExpansion

Set "STRING=%~1"
Set "specialChar=FALSE"

rem search for percent character in the 1-line file
For /F "tokens=*" %%i In ('FINDSTR /C:"%%" tmp.txt') Do (
   Set "strFound=%%i"
)

If defined strFound Set "specialChar=TRUE"& GoTo:endISC

If "%STRING%" NEQ == "%STRING:<=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:>=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:&=%" Set "specialChar=TRUE"
:endISC

endlocal & set "%~2=%specialChar%"& exit /b


mirrormirror
Posts: 129
Joined: 08 Feb 2016 20:25

Re: Test string for <, > or %

#4 Post by mirrormirror » 08 Feb 2016 21:52

Hello, can someone give a quick explanation or a link as to the function of: NEQ == (as seen in the code below).
- i.e. as opposed to either NEQ or ==

Thanks much

jeb wrote:Hi Jer,

the main problems are in the lines like

Code: Select all

If Not ."%STRING%".==.%1%. Set ...

The syntax is wrong, it should only be %1, and more important working here with %1 at all will only produce problems.
It's better to work only with the %string% variable

Code: Select all

:isSpecChar
setlocal DisableDelayedExpansion
rem check for chars % < and >

Set "specialChar=FALSE"
Set "STRING=%~1"

If "%STRING%" NEQ == "%STRING:<=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:>=%" Set "specialChar=TRUE"& GoTo:endISC
If "%STRING%" NEQ == "%STRING:&=%" Set "specialChar=TRUE"& GoTo:endISC
...

Ed Dyreen
Expert
Posts: 1569
Joined: 16 May 2011 08:21
Location: Flanders(Belgium)
Contact:

Re: Test string for <, > or %

#5 Post by Ed Dyreen » 09 Feb 2016 09:12

mirrormirror wrote:Hello, can someone give a quick explanation or a link as to the function of: NEQ == (as seen in the code below).
- i.e. as opposed to either NEQ or ==
Why are you doing this ?

Code: Select all

if something NEQ == something
Use Not-equals or Equals, using them together does not makes sense.

Code: Select all

:: test defined
if defined x ( do u ) else do v
if not defined x ( do u ) else do v
if %x%.==. ( do u ) else do v %= same as not defined =%

:: test equals
if %x% == %y% ( do u ) else do v
if %x% EQU %y% ( do u ) else do v %= same as == =%

:: test inequals
if not %x% == %y% ( do u ) else do v
if %x% NEQ %y% ( do u ) else do v %= same as not == =%
The other operators are LSS LEQ GEQ GTR.

mirrormirror
Posts: 129
Joined: 08 Feb 2016 20:25

Re: Test string for <, > or %

#6 Post by mirrormirror » 09 Feb 2016 16:01

Why are you doing this ?

I'm not doing it :) I saw it in Jeb's reply (#2) and was curious as to what it did and why it was used. Maybe he will see this and respond.

jeb
Expert
Posts: 1055
Joined: 30 Aug 2007 08:05
Location: Germany, Bochum

Re: Test string for <, > or %

#7 Post by jeb » 09 Feb 2016 18:15

mirrormirror wrote:I'm not doing it I saw it in Jeb's reply (#2) and was curious as to what it did and why it was used. Maybe he will see this and respond.

And I'm simply made a copy&paste error :oops:

Ed is right, use NEQ or == or one of the other keywords, but not two of them.

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: Test string for <, > or %

#8 Post by Jer » 09 Feb 2016 23:30

I am switching to another approach in displaying colored text.
Aacini's ColorShow.exe offers a big improvement in speed. I used Foxidrive's methods of reading and using
lines of text from a file.

This is a simple demo:

Code: Select all

@Echo Off
rem - requires the file ColorShow.exe from DOSTIPS.com
rem - demonstrates using spaces to present colored text on a fixed-width colored background
rem - do not include double or single quotes in the text file

setlocal
Set "file=sample.txt"
Set "myColors=1f"
Set /A indent=10

Set "indentSpace= "
setlocal EnableDelayedExpansion
For /L %%n In (1 1 %indent%) Do Set "indentSpace= !indentSpace!"
endlocal & set "indentSpace=%indentSpace:~0,-1%"

Call :longestLine "%file%" maxLength

Set /A maxLength+=4&rem 2-space left and right margins

Set "spaces= "
setlocal EnableDelayedExpansion
For /L %%n In (1,1,%maxLength%) Do Set "spaces= !spaces!"
endlocal & set "spaces=%spaces%"

For /f "tokens=1,* delims=:" %%a In ('findstr /nbv "~:_@_:~" "%file%" ') Do (
    Set "line-%%a=  %%b%spaces%"
    If "%%b"=="" Set "line-%%a= %spaces%"
    Set "numlines=%%a"
)

For /L %%a In (1,1,%numlines%) Do Set num=0&Call Set "line=%%line-%%a%%"&Call :show
Echo(& pause

endlocal & exit /b

::_________________________functions begin here____________________
:show
 Call Set "line=%%line:~0,%maxLength%%%"
 If %indent% gtr 0 ColorShow /07 "%indentSpace%"
 ColorShow /%myColors% "%line%"&Echo(
 GoTo:eof
 :: __________________________end show_____________________________


:strLength
 setlocal DisableDelayedExpansion

 Set /A length=0
 If "%~1"=="" GoTo:eLenLoop

 Set "temp=%~1%"

 :sLenLoop
 Set /A length+=1
 Set "temp=%temp:~1%"
 If "%temp%"=="" GoTo:eLenLoop
 GoTo:sLenLoop
 :eLenLoop

 endlocal& set "%~2=%length%"& exit /b
 :: __________________________end strLength________________________

:longestLine
 rem return the length of the longest line in text file (%1)
 setlocal EnableDelayedExpansion
 Set /A maxLen=0

 For /f "tokens=1,* delims=" %%a In ('findstr /bv "~:_@_:~" "%~1" ') Do (
    Call :strLength "%%a" len
    If !len! gtr !maxLen! Set /A maxLen=!len!
 )

 endlocal & set "%~2=%maxLen%"& exit /b



Put this text in sample.txt:

Code: Select all

The quick brown fox jumped over the lazy dog and went on his way.

                   Line Centered in Text File

Text is presented on a colored fixed-width background.

= & | $ # @ * ! > < / \ ? [] {} () ~ : % + - ^

Single or double quotes are not supported.

Control colored background indentation by setting the indent variable.
                                                                     

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Test string for <, > or %

#9 Post by foxidrive » 10 Feb 2016 08:07

I entertained myself and jiggered up this code.
The string length counting routine was snaffled from here in the past I think.

It should work the same but ! aren't supported either, and the text to be printed is inside the batch file itself.
Another extra limitation is that leading : characters are stripped out.

Code: Select all

@echo off
goto :are-we-there-yet?

The quick brown fox jumped over the lazy dog and went on his way.

                   Line Centered in Text File

Text is presented on a colored fixed-width background.

= & | $ # @ * ! > < / \ ? [] {} () ~ : % + - ^

Single or double quotes are not supported.  Don't use exclamation points either.

Control colored background indentation by setting the indent variable.

:are-we-there-yet?
setlocal EnableDelayedExpansion
set "indent=10"
Set "myColors=1f"

:: create the indent-using-spaces variable
for /L %%a in (1,1,%indent%) do call set indentspc= %%indentspc%%
:: create the outdent-using-spaces variable
for /L %%a in (1,1,250) do call set outdentspc= %%outdentspc%%

:: count the length of the longest line

for /f "skip=2 usebackq delims=" %%a in ("%~f0") do (
  if "%%a"==":are-we-there-yet?" goto :next
  set "s=%%a#" & set "len=0"
    for %%P in (4096 2048 1024 512 256 128 64 32 16 8 4 2 1) do (
        if "!s:~%%P,1!" NEQ "" set /a "len+=%%P" & set "s=!s:~%%P!")
  if !len! GTR !num! set "num=!len!"
)
:next

:: print the text using colorshow.exe
for /f "skip=2 tokens=1,* delims=:" %%a in ('findstr /n "^" "%~f0"') do (
if "%%b"=="are-we-there-yet?" goto :done
set "text=%%b%outdentspc%"
ColorShow "%indentspc%" /%myColors% "!text:~0,%num%!" &echo(
)
:done
endlocal
pause & goto :EOF

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: Test string for <, > or %

#10 Post by Jer » 10 Feb 2016 11:03

Thanks for your reworked and shortened version. Could you please
explain the double percent characters...how they differ from single % chars.

The variable outdentspc remains in the DOS environment after the batch file is run,
and the indent space grows each time the file is run in the same DOS session.

Aacini
Expert
Posts: 1914
Joined: 06 Dec 2011 22:15
Location: México City, México
Contact:

Re: Test string for <, > or %

#11 Post by Aacini » 10 Feb 2016 12:06

In my opinion your code is over-complicated! I taken the :ShowFileInFrame subroutine (that appears below Show.exe program description) and slightly modified it in order to use ColorShow.exe to show the lines over a color background (instead of use Show.exe to show the lines inside a frame).

Code: Select all

@echo off
setlocal EnableDelayedExpansion

Set "file=sample.txt"
Set "myColors=1f"
Set indent=3


:ShowFileInFrame filename

rem Count the number of lines in file
for /F %%a in ('find /C /V "" ^< "%file%"') do set "numLines=%%a"

rem Read file lines and get max line length
set maxLen=0
< "%file%" (for /L %%i in (1,1,%numLines%) do (
   set "line[%%i]="
   set /P "line[%%i]="
   set "str=0!line[%%i]!"
   set "len=0"
   for /L %%a in (8,-1,0) do (
      set /A "newLen=len+(1<<%%a)"
      for %%b in (!newLen!) do if "!str:~%%b,1!" neq "" set "len=%%b"
   )
   if !len! gtr !maxLen! set "maxLen=!len!"
   if !len! equ 0 set "line[%%i]= "
))
set /A "maxLen+=4"  & rem 2-space left and right margins

rem Show file lines on a fixed-width colored background
for /L %%i in (1,1,%numLines%) do ColorShow 32*%indent% /%myColors% line[%%i]:+%maxLen%  13 10

This is the new sample.txt file:

Code: Select all

The quick brown fox jumped over the lazy dog and went on his way.

                   Line Centered in Text File

Text is presented on a colored fixed-width background.

= & | $ # @ * ! > < / \ ? ' " [] {} () ~ : % + - ^

Single or double quotes ARE supported.

Control colored background indentation by setting the indent variable.
                                                                   

I used the capability of ColorShow.exe program to repeat several characters when "code*times" parameter is used (to show the indent), and the capability of auto-center a variable in a given width. This is the complete description of such features:

on Show.exe description Aacini wrote:Show characters from Ascii codes, string literals and Batch variables.

Show code[*times] | "literal" | variable[:[±]wide] ...

<code>, <times> and <wide> must be decimal numbers up to 255 each.

Times repeat the previous Ascii code character that number of times.
Wide define a width to show the variable value: justified at left, or justified at rigth if <wide> have minus sign, or centered if <wide> have plus sign.

At end, the number of displayed characters is returned in ERRORLEVEL.


Antonio

foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Test string for <, > or %

#12 Post by foxidrive » 10 Feb 2016 14:36

Jer wrote:Could you please explain the double percent characters...how they differ from single % chars.

They are useful with a technique using the call keyword, to allow the variable to expand in that one line.

When you use the call keyword in that way the command is executed in a child cmd process, and the doubled percent signs evaluate to a single percent sign, in a similar way to when you use echo %%.

The variable outdentspc remains in the DOS environment


Ahh yes, I moved the setlocal command and added the endlocal command to clear the variables when it finishes.

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: Test string for <, > or %

#13 Post by Jer » 11 Feb 2016 00:42

Foxidrive, thank you for all your help and explaining %%. One part is not clear to me:
in a similar way to when you use echo %%.
What does that mean?

Accini's batch file is pure magic, so that's what I'm working with; just to see if it can be
done and speedily. His short batch file made room for me to add more "complications", and
here's what I came up with after adding borders:

Code: Select all

@echo off
setlocal EnableDelayedExpansion

rem   display colored text in a colored area with optional border.
rem   Add 2 blank lines to bottom of text file to display blank line at end of text.

set "file=sample.txt"
set "myColors=1e"

set "bdrColors=1b"
rem set "bdrColors=" &rem this would disable borders

set indent=5

If defined bdrColors set /A indent+=2

:ShowFileInFrame filename

rem Count the number of lines in file
for /F %%a in ('find /C /V "" ^< "%file%"') do set "numLines=%%a"

rem Read file lines and get max line length
set maxLen=0
< "%file%" (for /L %%i in (1,1,%numLines%) do (
   set "line[%%i]="
   set /P "line[%%i]="
   set "str=0!line[%%i]!"
   set "len=0"
   for /L %%a in (8,-1,0) do (
      set /A "newLen=len+(1<<%%a)"
      for %%b in (!newLen!) do if "!str:~%%b,1!" neq "" set "len=%%b"
   )
   if !len! gtr !maxLen! set "maxLen=!len!"
   if !len! equ 0 set "line[%%i]= "
))
set /A "maxLen+=4"  & rem 2-space left and right margins when text centered

If defined bdrColors set /A "skipLeft=%indent%-4" & set /A "skipRight=%maxLen%+4"

rem Show file lines on a fixed-width colored background

If defined bdrColors ColorShow 32*%skipLeft% /%bdrColors% 176*%skipRight% 13 10

for /L %%i in (1,1,%numLines%) do (
   If defined bdrColors (
      ColorShow 32*%skipLeft% /%bdrColors% 176*2 /%myColors% line[%%i]:+%maxLen% /%bdrColors% 176*2 13 10
   ) Else (
     ColorShow 32*%indent% /%myColors% line[%%i]:+%maxLen%  13 10
   )
)

If defined bdrColors ColorShow 32*%skipLeft% /%bdrColors% 176*%skipRight% 13 10
GoTo:eof

rem ColorShow parameters explanation:
rem   32*%indent%  <repeat ASCII char 32 (space) the number of times in %indent%>
rem
rem   /%myColors%  <example values: /4e>
rem
rem   line[%%i]    <contains string of text or a blank for blank line dispay>
rem
rem   :+%maxLen%    <text is centered>
rem   :-%maxLen%    <text is right justified>
rem   :%maxLen%     <text is left justified>
rem
rem   13 10        <include carriage return (ASCII 13) and line feed (ASCII 10)>
rem


foxidrive
Expert
Posts: 6031
Joined: 10 Feb 2012 02:20

Re: Test string for <, > or %

#14 Post by foxidrive » 11 Feb 2016 03:14

Just some feedback here as the centering seems to have a glitch if you compare it with the text file below it.

BTW, if you type echo %% in a batch file then you will see only a single % sign.

Image

Jer
Posts: 177
Joined: 23 Nov 2014 17:13
Location: California USA

Re: Test string for <, > or %

#15 Post by Jer » 11 Feb 2016 10:53

Ok, now I understand the echo %% statement.

The centering thing is not a glitch, but a feature!
The latest sample.txt does not need to have the one centered
line. ColorShow.exe can center all lines, right justify all, and left justify all.

Now to the feature: If you choose the left justify option, you can get
individual centered lines by inserting leading spaces in the text file for those lines you
want centered.
Also, if you choose the same foreground and background colors in the borders as the
text area background color you get an extra colored margin surrounding
the text. You can see the benefit of this when you left-justify text; you have
a colored margin on the left side (as opposed to having no margin at all).

Post Reply