Hello @dshuman52, @alan-kilborn and All,
@dshuman52, Here is a method which could help you ! It works whatever the current language as it’s a recursive regular expression looking for well-balanced ( .... ) blocks, containing possible juxtaposed / nested other ( .... ) blocks !
SEARCH \((?:[^()]++|(?0))*\) ( Select the Regular expression search mode )
Notes :
From current location of the caret, this regex selects, automatically, the next longest well balanced ( .... ) block
If you prefer to get the ending parenthesis, only, simply change this regex as below :
SEARCH \((?:[^()]++|(?0))*\K\)
To explain this regex, the best is to use the free-spacing mode, which allows comments in regexes :
(?x) # FREE-SPACING mode
\( # STARTING parenthesis
(?: # Start of the NON-CAPTURING group
[^()]++ # Any NON-NULL ATOMIC range of ALLOWED characters
| # OR
(?0) # A RECURSION, using the WHOLE regex pattern ( group #0 )
)* # End of the NON-CAPTURING group, repeated 0 or MORE times
# \K # DELETE the initial '#' character, of that line, to match the ENDING parenthesis, ONLY
\) # ENDING parenthesis
Try this regex against your text, below :
@ECHO ON
REM LINKdir.bat
REM
REM %1 = A99LINK
REM %2 = A99TARGET
REM %3 = A99FILTER
REM
SET A99LINK=%~1
SET A99TARGET=%~2
SET A99FILTER=%~3
REM
REM make directories and link files
REM
PUSHD %A99TARGET:~0,-1%
REM
REM make directories
FOR %%F IN (DIR /ad /b) DO (
SET %A99FILE%=%%F
IF %A99FILE:~0,1%!='.' (
MKDIR %A99LINK%%A99FILE%
%A01TESTbatPATH%LINKdir.bat ^
%A99LINK%%A99FILE% ^
%A99TARGET%%A99FILE%
)
)
REM
REM link files
REM
FOR %%T IN (%A99FILTER%) DO (
FOR %%F IN (DIR /a-d /b *.%%T) DO (
SET %A99FILE%=%%F
IF %A99FILE:~0,1%!='.' (
MKLINK /h %A99LINK%%A99FILE% ^
%A99TARGET%%A99FILE%
)
)
)
POPD
Notes :
Place the caret at different locations, of this batch file
Then do the search hitting, several times, the F3 shortcut
Important :
Each time that a well-balanced ( .... ) block is selected :
An hit on the Left Arrow key moves the caret right before the ( starting parenthesis
An hit on the Right Arrow key moves the caret right after the ) ending parenthesis
The nice thing is that, when you hit the shift + F3 shortcut, it gets the inner ( ... ) block, closed to the end of the outer ( ... ) block !
Try also, with your first sample text :
DO %%F IN (z y x) DO (
IF %%F==x (
ECHO ‘x’
) ELSE (
IF %%F==y (
ECHO ^
‘y’
) ELSE (
IF %%F==z (
ECHO ‘z’
)
)
)
)
Best Regards,
guy038
P.S. :
In batch files , the & ampersand, the | vertical line and the ( and ) parentheses are special chars. So, they must be preceded with the escape character ^ or embedded inside double quotes.
Thus, here’s a more elaborate version, where we suppose that the ^ symbol is the default escape character and any character, preceded with a ^ symbol, is just considered as a literal chars, including the syntaxes ^( and ^) !
(?x) # FREE-SPACING mode
(?<!\\) # NEXT character is NOT PRECEDED with a '\' symbol ( LOOK-BEHIND condition )
\( # STARTING parenthesis
(?: # Start of the 1st NON-CAPTURING group
(?: # Start of the 2nd NON-CAPTURING group
\^ [()] # STRINGS '^(' or '^)' are supposed to be ALLOWED characters
| # OR
[^()] # Any ALLOWED character, even EOL ones, DIFFERENT of the PARENTHESES '(' and ')'
)++ # End of the 2nd NON-CAPTURING group ( NON-NULL ATOMIC range of ALLOWED characters )
| # OR
(?0) # A RECURSION, using the WHOLE regex pattern ( group #0 )
)* # End of the 1st NON-CAPTURING group, repeated 0 or MORE times
(?<!\\) # NEXT character is NOT PREDECED with a '\' symbol ( LOOK-BEHIND condition )
\) # ENDING parenthesis
Here is its shortest syntax :
SEARCH (?x)(?<!\\)\((?:(?:\^[()]|[^()])|(?0))*(?<!\\)\)
Test it against this sample text :
DO %%F IN (z y x) DO (
IF %%F==x (
ECHO ‘x’ ^(
) ELSE (
IF %%F==y (
ECHO ^
‘y’
) ELSE (
IF %%F==z (
ECHO ‘z’
)
)
^)
)
)