Batch - установить / сбросить параметры вызова подпрограммы с восклицательным знаком (!) И отложенным расширением? - PullRequest
0 голосов
/ 03 июня 2018

У меня есть 2 местных жителя, использующих отложенное расширение.1. Local вызывает подпрограмму, которая включает 2. Local, которая определяет 2 переменные и устанавливает их значения в качестве значений параметров, используя FOR /F ....Это прекрасно работает, если строка не содержит один или несколько восклицательных знаков.Следующий рабочий скрипт показывает проблему:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION

    CALL :get_substrings testString substr
    ECHO Inside 1. local:
    ECHO !testString!
    ECHO !substr!

    EXIT /B 0
ENDLOCAL


:get_substrings
    SETLOCAL ENABLEDELAYEDEXPANSION

    SET string="World^! wasserschutzpolizei^!"
    SET substring="Hello^!"
    ECHO Inside get_substrings:
    ECHO !string!
    ECHO !substring!

    FOR /F "delims=" %%s IN ("!string!") DO FOR /F "delims=" %%b IN ("!substring!") DO (
        ENDLOCAL & SET "%1=%%s" & SET "%2=%%b" & EXIT /B 0
    )
EXIT /B 0

Вывод:

Inside get_substrings:
"World! wasserschutzpolizei!"
"Hello!"
Inside 1. local:
"World"
"Hello"

Ожидается:

Inside get_substrings:
"World! wasserschutzpolizei!"
"Hello!"
Inside 1. local:
"World! wasserschutzpolizei!"
"Hello!"

Если вы удалите восклицательные знаки в string иsubstring скрипт работает как положено.

Поскольку это только пример, рассмотрим ...

  1. Не использовать отложенное расширение не вариант, а также ...
  2. Использование одного Local нежелательно.

Конечно, если ДЕЙСТВИТЕЛЬНО требуется одна или обе вещи, и нет другого способа, которым я принимаю другие ответы, указывающие на это.

Итак ...

  1. Как получить значения с восклицательным знаком в 1. локальном, как я показал в Ожидаемая часть?
  2. Почему нетэто работает с текущим способом установки значений параметров?

Цените вашу помощь!

Ответы [ 2 ]

0 голосов
/ 04 июня 2018

Можно ли отключить отложенное расширение при вызове подпрограммы:

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS DISABLEDELAYEDEXPANSION

    CALL :get_substrings testString substr
    SETLOCAL ENABLEDELAYEDEXPANSION
    ECHO Inside 1. local:
    ECHO !testString!
    ECHO !substr!
    ENDLOCAL

    EXIT /B 0
ENDLOCAL


:get_substrings
    SETLOCAL ENABLEDELAYEDEXPANSION

    SET string="World^! wasserschutzpolizei^!"
    SET substring="Hello^!"
    ECHO Inside get_substrings:
    ECHO !string!
    ECHO !substring!

    FOR /F "delims=" %%s IN ("!string!") DO FOR /F "delims=" %%b IN ("!substring!") DO (
        ENDLOCAL & SET "%1=%%s" & SET "%2=%%b" & EXIT /B 0
    )
EXIT /B 0

Это позволит избежать расширения for переменных %%s и %%b при отложенном расширениивключен, потому что это последний шаг, поэтому восклицательные знаки стали расходоваться.

0 голосов
/ 04 июня 2018

Измените возвращаемую часть вашей функции: get_substrings на:

...
set "return1=!string:"=""!"
set "return1=%return1:!=^^^!%"
set "return1=!return1:""="!"

set "return2=!substring:"=""!"
set "return2=%return2:!=^^^!%"
set "return2=!return2:""="!"

FOR /F "delims=" %%s IN ("!return1!") DO FOR /F "delims=" %%b IN ("!return2!") DO (
    ENDLOCAL & SET "%1=%%s" & SET "%2=%%b" & EXIT /B 0
)

Но почему ваше решение терпит неудачу?
Проблема в том, что set "%1=%%s" выполняется в контексте отложенного расширения, так как вашполная партия использует отложенное расширение.
Но отложенное расширение - это последняя фаза расширения пакетного анализатора, и это после расширения параметра %%s.
Поэтому анализатор пытается расширить ваши восклицательные знаки, когда здесь толькоодин он будет удален, когда есть два, как в "World! wasserschutzpolizei!", он расширяет переменную ! wasserschutzpolizei! до ее значения (в вашем случае она кажется пустой).

Решение просто помещает каретки перед любым восклицательным знаком.
Но вы также используете кавычки в своих примерах, что усложняет задачу.
Чтобы избежать проблем с кавычками и каретками, это легкоспособ удвоить все кавычки, добавить каретки и изменить двойные кавычки обратно на одинарные кавычки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...