У меня есть строка, возвращаемая вызовом API, это что-то вроде
".\controllers\myaction c:\test\path"
Я хочу использовать Powershell, чтобы проверить, содержит ли строка c:\
Как я могу это сделать?
Я пробовал следующее:
# if $result is populated with the string above then i do
if ($result.context.ToLower().Contains("c:\") -eq "True")
{
#code here
}
как я могу это сделать?
В вашем коде нет ничего плохого? '.\controllers\myaction c:\test\path'.ToLower().Contains('c:\')
это true
. Просто уберите -eq "True"
из состояния.
Для корректной работы вы должны исключить эту -eq "True"
часть из своего кода, поскольку оператор if
проверяет два условия:
$result.context.ToLower()
: преобразует всю строку в $result.context
в нижний регистр, гарантируя, что проверка нечувствительна к регистру.
.Contains("c:\")
: проверяет, содержит ли версия строки в нижнем регистре подстроку "c:\"
.
В -eq "True"
нет необходимости: метод «Содержит» уже возвращает логическое значение ($true
или $false
), поэтому вы можете напрямую использовать его в операторе if.
Следовательно, код должен быть: -
if $result is populated with the string above then i do
if ($result.context.ToLower().Contains("c:\"))
{
#code here
}
Если я уберу -eq «True», то как мне проверить, не содержит ли он ?
Как я уже упоминал, функция возвращает логическое значение. Если условие ложно, оператор if
не будет выполнен. Вы можете использовать оператор else
или else if
для обработки ложного сценария. Надеюсь, это поможет!
Чтобы дополнить полезный ответ Пратикшита Джайсвала правдой о -eq "True"
:
если это действительно касается «строки, возвращаемой вызовом API», лишний -eq "True"
не является проблемой:
(although I would really recommend against adding that.)
if (".\controllers\myaction c:\test\path".ToLower().Contains("c:\") -eq "True") {
Write-Host 'code here'
}
code here
Это связано с тем, что PowerShell — это слабо типизированный язык, где левая часть (LHS) условия определяет метод сравнения. Это означает, что если LHS является логическим значением:
".\controllers\myaction c:\test\path".ToLower().Contains("c:\") -is [Bool]
True
RHS имеет логический тип:
[Bool]"True"
True
Поскольку обе стороны $True
, условие просто считается $True
(или правдивым).
Так что же здесь на самом деле происходит?
Я подозреваю, что $result.context
на самом деле не строка, а что-то вроде массива строк:
$result = @{ context = ".\controllers\myaction", "c:\test\path" }
$result.context
.\controllers\myaction
c:\test\path
Или :
"$($result.context)"
.\controllers\myaction c:\test\path
Перечисление доступа к членам PowerShell — хорошая функция, но она часто приводит к путанице:
если вы используете метод .ToLower()
(строка) для строкового массива, это будет работать чудесно:
$result.context.ToLower()
.\controllers\myaction
c:\test\path
Но поскольку метод .Contains
также является методом массива, вы можете увидеть неожиданные результаты:
$result.context.ToLower().Contains("c:\")
False
Это связано с тем, что массив не содержит (полную) строку "c:\"
. Где он содержит строку:
$result.context.ToLower().Contains("c:\test\path")
True
Обратите внимание: на самом деле нет смысла использовать здесь метод .ToLower()
, поскольку по умолчанию PowerShell выполняет сравнение без учета регистра.
Тем не менее, этот метод .ToLower()
может еще больше запутать ситуацию, поскольку он «разворачивает» любой массив с одним элементом до самого элемента:
@{ context = @("c:\test\path") }.context.GetType().Name
Object[]
против:
@{ context = @("c:\test\path") }.context.ToLower().GetType().Name
String
Это объясняет любой неожиданный результат в отношении:
@{ context = @("c:\test\path") }.context.Contains("c:\")
False
против:
@{ context = @("c:\test\path") }.context.ToLower().Contains("c:\")
True
К сожалению, я не могу дать вам точный ответ, так как не знаю фактический тип данных и структуру $result.context
(вы можете добавить результаты $result.context.GetType().Name
и $result.context | ConvertTo-Json -Depth 9
к вашему вопросу), но я надеюсь, что это может прояснить некоторые вопросы. что касается поведения PowerShell, связанного с вашей проблемой.
Как насчет использования оператора
match
? about_Comparison_Operators