【问题标题】:Powershell: How to Validate Range between 1 to 15 and it should accepts pattern as 1,2,3,4,5 to 15Powershell:如何验证 1 到 15 之间的范围,它应该接受 1、2、3、4、5 到 15 的模式
【发布时间】:2015-07-01 15:51:27
【问题描述】:

我是 Power Shell 脚本的新手。 我正在尝试实现一个功能,该功能应该接受来自以下标准的用户输入

  1. 只有数字
  2. 范围在 1 到 15 之间
  3. 应接受以逗号分隔的数组字符串,例如:1、2、3、4、14、15
  4. 逗号之间可以包含空格
  5. 值不应重复
  6. 返回值必须是数组

到目前为止,我已经尝试过

Function Validate-Choice{
[cmdletbinding()]
Param(
[Parameter(Position=0,Mandatory=$True)]
[ValidateRange(1,15)]
[string[]]$Item
)
Process {$Item}
}
Validate-Choice 1,2,3,4,5,6,7,8,9,10,11,13 # Similar Way i want O/p

Out Put: 
     1
     2
     3
     4
     5
     6
     7
     8
     9
     10
     11
     13


 $ReadInput = Read-Host  -prompt "Please Choose from the list [1/2/3/4/5/6/7/8/9/10/11/12/13/14] You can select multiple Values  EX: 1, 2, 3 --  "
 $userchoices = Validate-Choice -item $ReadInput
 $userchoices

If read the same input from Host Getting Below Error

Validate-Choice : Cannot validate argument on parameter 'Item'. The argument    cannot be validated because 
its type "String" is not the same type (Int32) as the maximum and minimum limits of the parameter. Make sure the argument is of type Int32 and then try  the command again. At line:10 char:21
+     Validate-Choice '1,2,3,4,5,6,7,8,9,10,11,13'
+                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidData: (:) [Validate-Choice],   ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Validate-Choice

我也在尝试不同的正则表达式模式。但是失败了

Function Test-Something {
[cmdletbinding()]
Param(
    [Parameter(Position=0,Mandatory=$True)]
    [ValidatePattern('(?:\s*\d{1,15}[1-15]\s*(?:,|$))+$')]
    [string[]]$Item
)
Process { $Item }
}

上述函数是部分生成的。 任何人都可以在这里帮助我..!?

【问题讨论】:

  • \d{1,15} 表示长度在 1 到 15 位之间的数字。 [1-15] 不是你可以做的数字 1-15 ([1-9]|1[0-5])[] 是特定字符或单个字符范围的字符类。例如,a-z 适用于小写字母字符,0-9 适用于数字 0 到 9。对于 9 及更高版本,您需要添加 + 或添加条件(也适用于小数)。
  • 谢谢..!克里斯85。您能否提供完整的正则表达式模式来做到这一点?
  • 我没有 powershell,所以无法测试。我可以编写一个我认为可行的正则表达式。

标签: regex powershell


【解决方案1】:

如果您只是将参数类型更改为[int[]],那么这可能是最简单的,然后您的 ValidateRange 属性会完成大部分工作。但它不处理重复项。事实证明你不能使用 [ValidateScript()] 正如@PetSerAl 指出的那样。这样就可以在开始块中以老式方式检查参数:

Function Test-Something {
    [cmdletbinding()]
    Param(
        [Parameter(Position=0, Mandatory)]
        [ValidateRange(1, 15)]
        [int[]]$Item
    )

    Begin {
        $ht = @{}
        foreach ($i in $Item) {
            if ($ht.ContainsKey("$i")) {
                throw "Parameter Item must contain unique values - duplicate '$i'"
            } 
            else {
                $ht["$i"] = $i
            }
        }
    }

    Process { 
        [string]$Item 
    }
}

Test-Something (1,2,3,4,3)

请注意,如果您让 Item 参数接受管道输入,这将不起作用。在管道输入情况下,begin 块中不会设置 $Item。

【讨论】:

  • 感谢基思希尔..!但是我们可以传递像 1,2,3,5... ,15 这样的输入吗?如果我通过 1 到 15。这将循环到 15 次。我们能否创建更可靠的 sn-p 来满足性能?
  • 如果您的范围真的是 1 到 15,我认为 ValidateScript 的性能不会那么差。现在如果范围是 1..10000 那么是的,性能可能是个问题。
  • ValidateScript 为集合的每个元素而不是集合本身运行脚本,因此您无法通过这种方式检查重复项。
  • @KeithHill,该功能正在运行。我正在使用这样的` $ReadInput = (Read-Host -prompt "Please Choose etc...") -split ',' $userchoices = Test-Something -item $ReadInput $userchoices.split(" ") `跨度>
  • @KeithHill,但是每当我传递错误的输入数据和 PS 抛出错误时,$userchoices 都会返回上一组结果。
【解决方案2】:

Naren_Ch

您第一次使用高级功能 (AF)

Validate-Choice 1,2,3,4,5,6,7,8,9,10,11,13 # Similar Way i want O/p

是正确的 - 您正在按照 AF 的预期输入数据。

现在,看看从主机读取输入的示例:

$ReadInput = Read-Host  -prompt "Please Choose from the list [1/2/3/4/5/6/7/8/9/10/11/12/13/14] You can select multiple Values  EX: 1, 2, 3 --  "

当你这样做时,$ReadInput 是一个字符串,在这种情况下,它是一个充满逗号的字符串! 因此,您输入到AF的数据将导致您自己编写的验证码导致错误。

要纠正这种情况,只需这样做:

$ReadInput = (Read-Host  -prompt "Please Choose etc...") -split ','
$userchoices = Validate-Choice -item $ReadInput

你必须记住Read-Host读取的数据是一个字符串(只有1个字符串)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 2011-05-20
    相关资源
    最近更新 更多