преобразовать да или нет в логическое значение

Я хочу проанализировать пользовательские значения, содержащиеся в файле .CSV. Я не хочу, чтобы мои пользователи вводили «Да» или «Нет», а вместо этого вводили «Истина» или «Ложь». В каждом случае я хочу преобразовать в эквивалентные логические значения: $true или $false. В идеале я хотел бы значение по умолчанию, поэтому, если есть опечатка «Да» или «Нет», я бы вернул значение по умолчанию: $true или $false.

Следовательно, я задавался вопросом, есть ли аккуратный способ сделать это, кроме

if(){} else (){}

person westerdaled    schedule 29.03.2016    source источник
comment
У меня есть проблемы с вашей оговоркой об «орфографической ошибке». Итак, вы говорите, что если пользователь вводит «иену», вы хотите, чтобы это было $true? Каковы условия? Первая буква должна совпадать?   -  person gravity    schedule 29.03.2016


Ответы (7)


Один из способов — оператор switch:

$bool = switch ($string) {
  'yes' { $true }
  'no'  { $false }
}

Добавьте предложение default, если вы хотите обрабатывать значения, которые не являются ни «да», ни «нет»:

$bool = switch ($string) {
  'yes'   { $true }
  'no'    { $false }
  default { 'neither yes nor no' }
}

Другим вариантом может быть простое сравнение:

$string -eq 'yes'            # matches just "yes"

or

$string -match '^y(es)?$'    # matches "y" or "yes"

Эти выражения будут оцениваться как $true, если строка соответствует, иначе как $false.

person Ansgar Wiechers    schedule 29.03.2016
comment
не забудьте пункт default - person JamesQMurphy; 29.03.2016
comment
Использование -ieq и -imatch сделает их нечувствительными к регистру. - person Eris; 29.03.2016
comment
Операции сравнения @Eris PowerShell по умолчанию нечувствительны к регистру. Вам нужно использовать -ceq/-cmatch, чтобы сделать их чувствительными к регистру. - person Ansgar Wiechers; 29.03.2016
comment
@Ансгар Большое спасибо. Я ненавижу печатать, поэтому я проверю соответствие $string - думаю, мне нужно изучить регулярное выражение ;-). Будьте добры, если работали с yes и YES - person westerdaled; 29.03.2016
comment
Вместо '^y(es)?$' вы также можете использовать -like 'y*' - person Eris; 29.03.2016
comment
-like 'y*' будет соответствовать любой строке, начинающейся с y. Я подумал, что это может быть слишком широко, поэтому решил не указывать этот вариант. - person Ansgar Wiechers; 29.03.2016

Ах, магия функций powershell и вызов выражения.

function Yes { $true }
function No { $false }

$magicBool = & $answer 

Примечание. Это нечувствительно к регистру, но не обрабатывает опечатки.

person Eris    schedule 29.03.2016
comment
Это все веселье и игры, пока кто-нибудь не наберет rd *. - person beatcracker; 30.03.2016
comment
ОП сказал, что они анализируют файл, я предполагаю, что они контролируют ввод. - person Eris; 30.03.2016

Если единственными возможными значениями являются «Да» и «Нет», то, вероятно, самым простым способом является

$result = $value -eq 'Yes'

Со значениями с ошибками и значением по умолчанию $false тоже самое.

Со значениями с ошибками и значением по умолчанию $true это будет работать

$result = $value -ne 'No'
person Roman Kuzmin    schedule 29.03.2016
comment
$result = $ForcePasswordChange -ne 'No' кажется наиболее элегантным решением, поскольку я хочу, чтобы значение по умолчанию было $true, если только клиент явно не запрашивает это. Множество хороших предложений всем. Спасибо - person westerdaled; 29.03.2016

Все это верные подходы. Если вы ищете один вкладыш, это подтвердит, что это приемлемое значение, и установит логическое значение true, если установлено значение «истина». Это также даст вам значение $false по умолчанию.

$result = @("true","false","yes","no") -contains $value -and @("true","yes") -contains $value

Для значения $true по умолчанию вам понадобится что-то вроде этого.

$result = $true

if (@("true","false","yes","no") -contains $value) {
    $result = @("true","yes") -contains $value
}
person Jim    schedule 05.01.2017

Без полного фрагмента вашего существующего кода что-то вроде этого, вероятно, будет альтернативным путем, а не строкой операторов IF.

ПРИМЕЧАНИЕ. Это не будет обрабатывать простой ввод «Y» или «N», но нечувствителен к регистру. Таким образом, вы также должны увидеть, как работает «yes» или «YES».

$myVar = Read-Host 'What is your answer?'
switch ($myVar)
{
  Yes {$myVarConverted = $true; break}
  True {$myVarConverted = $true; break}
  No {$myVarConverted = $false; break}
  False {$myVarConverted = $false; break}
  default {"Invalid Input"; break}
}
Write-Host $myVarConverted

Пожалуйста, смотрите мой дополнительный комментарий к вашему вопросу об оговорке об «орфографической ошибке». Это сложно кодировать без конкретных ограничений или требований.

person gravity    schedule 29.03.2016

Вот как я отвечаю Да-Нет:

function ask-user
{
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory=$true)]
      [string] $question
   )
   Process
   {  $answer = read-Host $question
      if ("yes" -match $answer) {$true}
      elseif ("no" -match $answer) {$false}
      else {ask-user $question}
   }
}

Вы можете легко заменить "да" и "нет" на "истина" и "ложь".
Этот вариант нечувствителен к регистру и будет соответствовать допустимым сокращениям. (Д или Н). В случае орфографических ошибок он спрашивает снова. Да, я мог бы сделать это без рекурсии, но я ленив.

person Walter Mitty    schedule 29.03.2016
comment
Я вижу, что вы делаете, вы заставляете да или нет еще раз спросить. Я мог бы использовать верхний регистр, чтобы это тоже обрабатывалось. Хорошее предложение. - person westerdaled; 07.04.2016
comment
Это нечувствительно к регистру, потому что так работает -match. Я пробовал с большой буквы Y или N. - person Walter Mitty; 07.04.2016

Это отличные решения выше, но позвольте мне сказать, что вся эта тема только доказывает огромные недостатки Powershell...

  [System.Convert]::ToBoolean("False") -eq $true ? 
  [System.Convert]::ToBoolean("0") -eq $true ?  

Действительно? Дайте мне гребаный перерыв.

person m1m1k    schedule 18.11.2017