Чтобы ответить на общий вопрос в заголовке:
Самый безопасный способ вставить произвольное значение переменной в регулярное выражение - :
до first escape значение с [regex]::Escape($var)
, которое гарантирует, что значение будет трактоваться как литерал (метасимволы регулярных выражений, такие как .
являются \
-экранированными).
и затем встраивают его в одиночную кавычку через -f
,(строка) оператор формата , который позволяет встраивать операнды RHS через индексированные заполнители в строку формата LHS;например, {0}
- первый операнд RHS, {1}
- второй и т. д .;используйте {{
и }}
для экранирования литерала {
и }
.
Для пример для создания регулярного выражения, соответствующего произвольному значению $var
если ему предшествует одна или несколько цифр (\d+
) на границе слова (\b
) и если он расположен в конце строки ($
)
# 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
Asдля вашей конкретной проблемы WinForm :
.Controls.Find()
в форме / элементе управления WinForm позволяет искать элементы управления только по их полному, буквальному имени, а не по регулярному выражению.
Поэтому вы должны рекурсивно перечислять все элементы управления и сопоставлять их значения свойств .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
) по умолчанию нечувствительно по умолчанию, как и PowerShell в целом.
Что касается проблемы с вашим исходным регулярным выражением :
Не используйте '...'
(буквальные строки), если вы хотите встроить в него выражения, такие как [regex]::escape($name)
.
Для этого необходимо использовать расширяемую строку ("..."
) и встроить выражение внутри$(...)
, а не (...)
- как показано в ответе @ TobyU.
Альтернативадолжен использовать -f
, оператор форматирования строки, как показано выше.
Как правило, PowerShell не имеет синтаксиса регулярных выражений, он просто использует строки,поэтому не используйте /.../
внутри строки, представляющей регулярное выражение.