Пакет Windows проверяет, начинается ли переменная, заканчивается ли и содержит определенную строку

Я пытаюсь проверить, будет ли переменная в пакетном файле с " содержать BETA где-то и заканчивается на ").

Возможно ли это? И если да, может ли кто-нибудь помочь мне в этом?

Ответ 1

@ECHO OFF
SETLOCAL
SET var=abc&CALL :check
SET var="abc"&CALL :llcheck
SET var="")&CALL :check
SET var=")"&CALL :llcheck
SET var=abc")"&CALL :llcheck
SET var=xyzbetazyx&CALL :check
SET var="xyzbetazyx"&CALL :llcheck
SET var=xyzbetazyx")"&CALL :llcheck
SET var=xyzbetazyx")"&CALL :check
SET var="xyzbetazyx")&CALL :check
GOTO :eof
:: Lop last, then check
:llcheck
SET var=%var:~0,-1%
:check
SET result=N
SET var2=%var%
SET varvar=%var%

>test1.txt ECHO %var:~0,1%%var:~-2%
>test2.txt ECHO "")
FC test1.txt test2.txt >nul
IF ERRORLEVEL 1 GOTO done
SET var|FINDSTR /b "var="|FINDSTR /i "beta" >nul
IF ERRORLEVEL 1 GOTO done
SET result=Y
:done
ECHO %var% starts " has BETA and ends ") : %result% 
GOTO :eof

Где там будет...

Установка переменных с неуравновешенным " может быть сложной задачей. Я просто настроил его на сбалансированный и убрал последний символ (:llcheck entry: lop last и check.

Essentiall, я скопировал переменную в var2 и varvar в другой для демонстрации того, что произойдет, если эти переменные будут установлены.

Затем генерируются два файла. TEST1.TXT содержит первый и последний 2 символа var и TEST2.TXT просто "")

Сравните два - если они не идентичны, то переменная НЕ запускает " и заканчивается ") В противном случае хорошо - может просто записать var в файл и использовать findstr для поиска beta, но я решил отправить вывод SET var, который должен быть содержимым ALL переменных var* в форме

var=abc
var2=abc
varvar=abc

в findstr, найдя ту, которая начинается (/b) var=, и обнаруживает, содержит ли THAT строку beta. /i выбирает регистр без учета регистра. Если вы хотите специально beta в UPPER-CASE, просто измените beta на beta и удалите /i.

result установлен на Y или N

Ответ 2

Предполагая, что ваша переменная не содержит строк или возвратов каретки, тогда все, что требуется, - это одна команда FINDSTR. Он имеет ограниченную поддержку регулярных выражений, что более чем достаточно для этой проблемы.

@echo off
setlocal
set test1=abc
set test2="abc"
set test3="")
set test4=")"
set test5=abc")"
set test6=xyzBETAzyx
set test7="xyz BETA zyx"
set test8=xyzBETAzyx")"
set test9=xyzBETAzyx")"
set test10="xyzbetazyx")
set test11="xyzBETAzyx")

for /l %%N in (1 1 11) do call :test test%%N
exit /b

:test  variableName
setlocal enableDelayedExpansion
echo !%1!|>nul findstr /rx \".*BETA.*\") && set "result=PASS" || set "result=FAIL"
echo %1 = !result!: !%1!
exit /b

Проходит только TEST11.

Параметр /R заставляет строку поиска обрабатываться как регулярное выражение.

Параметр /X означает, что он должен быть точным совпадением - вся строка должна соответствовать строке поиска.

.* - это выражение подстановки регулярного выражения, которое будет соответствовать любой строке символов.

Я перенаправляю вывод FINDSTR в NUL, потому что нам не нужно видеть строку. Нам просто нужен код возврата

FINDSTR требует, чтобы литералы двойных кавычек были экранированы как \"

Используйте задержанное расширение, чтобы вы могли безопасно эхоиздать любое значение внутри переменной.

Я использую &&, чтобы условно принять меры, когда FINDSTR удалось, и ||, чтобы условно принять меры, когда FINDSTR не удалось.

Моя подпрограмма :TEST принимает имя переменной как единственный аргумент.

Обратите внимание, что в некоторых ситуациях парсерный парсер требует, чтобы вы также избежали двойной кавычки как ^", что означает, что полностью экранированная цитата будет выглядеть как \^". Но это осложнение не требуется в вашем случае. Правила выхода из программы FINDSTR на самом деле немного неловкие. См. Каковы недокументированные функции и ограничения команды Windows FINDSTR? для получения дополнительной информации.

Мой тестовый код выполняет поиск с учетом регистра. Таким образом, beta не будет соответствовать beta. Если вы хотите нечувствительный к регистру поиск, просто добавьте опцию /I.

EDIT: 2015-07-22

Другая опция, если и только если вы хотите проигнорировать случай, заключается в использовании комбинации операций поиска/замены переменных расширения и расширений. Оба теста 10 и тест11 проходят ниже.

@echo off
setlocal
set test1=abc
set test2="abc"
set test3="")
set test4=")"
set test5=abc")"
set test6=xyzBETAzyx
set test7="xyz BETA zyx"
set test8=xyzBETAzyx")"
set test9=xyzBETAzyx")"
set test10="xyzbetazyx")
set test11="xyzBETAzyx")

for /l %%N in (1 1 11) do call :test test%%N
exit /b

:test  variableName
setlocal enableDelayedExpansion
set "result=FAIL"
if "!%1:beta=!" neq "!%1!" if "!%1:~0,1!" equ ^""" if "!%1:~-2!" equ ^"")" set "result=PASS"
echo %1 = !result!: !%1!
exit /b

Первый IF проверяет на beta где угодно (без учета регистра). Второй IF проверяет на " в начале, а последний IF проверяет на ") в конце. Единственная сложная задача - выяснить, как избежать строки сравнения, когда она имеет нечетное количество кавычек.

Ответ 3

@echo off
setlocal EnableDelayedExpansion
set quote="
set variable="This must be true: BETA")
echo Variable=!variable!
if "!variable:~0,1!" equ "!quote!" (
   rem Start with "
   if "!variable:BETA=!" neq "!variable!" (
      rem Contains BETA
      if "!variable:~-2!" equ "!quote!^)" (
         echo TRUE: it start with " contains BETA and ends with "^)
      ) else (
         echo FALSE, it does not ends with "^)
      )
   ) else (
      echo FALSE, it does not contain BETA
   )
) else (
   echo FALSE, it does not start with "
)

Вывод:

Variable="This must be true: BETA")
TRUE: it start with " contains BETA and ends with ")
  • Способом борьбы с неуравновешенными кавычками (и с другими специальными командами Batch) является использование Delayed Expansion: таким образом, кавычки и специальные символы не отображаются в анализируемой командной строке.

  • Не забудьте сбежать с ^ любыми правыми круглыми скобками, которые не закрывают круглые скобки командных блоков.

  • Простой способ проверить, содержит ли переменная содержащую заданную строку, попытаться исключить строку из значения переменной: если результат отличается от исходного значения, то переменная содержит строку.

Антонио