Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式中的变量_Regex_Winforms_Powershell - Fatal编程技术网

Regex 正则表达式中的变量

Regex 正则表达式中的变量,regex,winforms,powershell,Regex,Winforms,Powershell,表单上有一些控件需要在函数中搜索,为此我决定使用控件。查找,函数的输入是$name。在这种情况下,搜索在文本框中运行,并添加到数组中以进行进一步的工作文本框名称表示为IPTextBox1,IPTextBox2等。正如我所写,以及它的工作原理(NetworkForm是一个包含所有控件的表单): 您可以先构建一个模式字符串,然后再使用它 $pattern = "/^($([regex]::escape($name)))[A-Z]{1}[a-z]{3}[A-Z]{1}[a-z]{2}.{1}$/" $

表单上有一些控件需要在函数中搜索,为此我决定使用
控件。查找
,函数的输入是
$name
。在这种情况下,搜索在
文本框中运行,并添加到数组中以进行进一步的工作<代码>文本框
名称表示为
IPTextBox1
IPTextBox2
等。正如我所写,以及它的工作原理(
NetworkForm
是一个包含所有控件的表单):


您可以先构建一个模式字符串,然后再使用它

$pattern = "/^($([regex]::escape($name)))[A-Z]{1}[a-z]{3}[A-Z]{1}[a-z]{2}.{1}$/"
$TextBoxes = $NetworkForm.Controls.Find($pattern, 1)

要回答标题中的一般问题,请执行以下操作:

在正则表达式中嵌入任意变量值的最安全方法是:

  • 首先使用
    [regex]:escape($var)
    对值进行转义,这确保将该值视为文本(regex元字符,如
    \
    -转义的)

  • 然后通过
    -f
    将其嵌入一个带引号的字符串中,该字符串允许通过LHS格式字符串中的索引占位符嵌入RHS操作数;e、 例如,
    {0}
    是第一个RHS操作数,
    {1}
    是第二个,依此类推;使用
    {{
    }
    转义文本
    {
    }

对于示例,如果在单词边界(
\b
)前面有一个或多个数字(
\d+
),并且位于字符串末尾(
$
),则构造与任意值
$var
匹配的正则表达式


至于您的特定WinForm问题

在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没有正则表达式文字语法,它只使用字符串,所以不要在表示正则表达式的字符串中使用
    /…/


Worth更清楚地解释问题。这不是问题所在。你基本上只是重写了一些已经写好的东西。任何文本都可以进入函数输入。我有很多控件,称为IP/DNS/MaskTextBox,我需要精确地按照输入的内容执行搜索,而不是完全按照IP执行搜索。问题是正则表达式写得不正确,因为我不知道如何正确使用[regex]::escape()。我用它在正则表达式中添加一个变量。也就是说,搜索应该像控件一样工作。Find([$name]TextBox,$true),其中$name可以是任何内容
# 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
# 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 }