在函数中需要搜索表单上的控件,为此,我决定使用Controls.Find
,函数的输入为$name
。在这种情况下,搜索将在TextBox
之间进行,并添加到数组中以进行进一步的工作。 TextBox
的名称表示为IPTextBox1
,IPTextBox2
等。正如我所写的以及它是如何工作的(NetworkForm
是包含所有控件的一种形式):
$TextBoxes = $NetworkForm.Controls.Find('/^([regex]::escape($name))[A-Z]{1}[a-z]{3}[A-Z]{1}[a-z]{2}.{1}$/', 1)
答案 0 :(得分:1)
您可以先构建一个模式字符串,然后再使用它。
$pattern = "/^($([regex]::escape($name)))[A-Z]{1}[a-z]{3}[A-Z]{1}[a-z]{2}.{1}$/"
$TextBoxes = $NetworkForm.Controls.Find($pattern, 1)
答案 1 :(得分:1)
要回答标题中的通用问题:
在正则表达式中嵌入任意变量值的最安全的方法是:
使用[regex]::Escape($var)
首先转义该值,以确保该值被视为 literal (正则表达式元字符(例如.
被转义了\
)。
,然后通过-f
({string} format operator)将其嵌入到单引号字符串中,该字符串允许嵌入通过LHS格式字符串中的索引占位符对RHS操作数进行设置;例如,{0}
是第一个RHS操作数,{1}
是第二个,以此类推;使用{{
和}}
转义文字{
和}
。
对于示例,构造一个与任意值$var
相匹配的正则表达式,如果该正则表达式在单词边界({{1})前面有一个或多个数字(\d+
)。 })(如果位于字符串(\b
)的末尾
$
关于您的特定WinForm问题:
在WinForm表单/控件上的 .Controls.Find()
仅允许按控件的全名而不是正则表达式来搜索控件。
因此,您必须递归枚举所有控件,并分别匹配其# The value to embed in the regex, to be interpreted as a *literal*.
$var = '$'
# Embed the escaped value in the regex.
# This results in the following regex - note the \-escaped $
# \b\d+\$$
$regex = '\b\d+{0}$' -f [regex]::Escape($var)
# Perform matching:
'Cost: 20$' -match $regex # -> $true
属性值。
请注意,不需要控件具有名称。
鉴于没有内置方法可以对表单/控件中包含的控件执行递归枚举,因此您必须首先自己实现,然后使用.Name
进行过滤正则表达式:
-match
请注意使用# Example:
# Get-ChildControl -Recurse $form
function Get-ChildControl {
param([System.Windows.Forms.Control] $Control, [Switch] $Recurse)
foreach ($child in $Control.Controls) {
$child
if ($Recurse) { Get-ChildControl -Recurse:$Recurse $child }
}
}
$regex = '^{0}[A-Z]{1}[a-z]{3}[A-Z]{1}[a-z]{2}.{1}$' -f [regex]::Escape($name)
$TextBoxes = Get-ChildControl -Recurse $NetworkForm | Where { $_.Name -cmatch $regex }
进行区分大小写的 匹配。
默认情况下,-cmatch
(及其别名-match
)不区分大小写 。
关于原始正则表达式的问题:
如果要在其中嵌入-imatch
之类的表达式,请不要使用'...'
(文字字符串)。
为此,您必须使用可扩展字符串([regex]::escape($name)
)并将表达式嵌入"..."
而不是$(...)
内-如@TobyU的答案所示。
替代方法是使用(...)
(字符串格式化运算符,如上所示)。
通常,PowerShell没有正则表达式文字语法,它仅使用字符串,因此请勿在代表正则表达式的字符串中使用-f
。