PowerShell WinForms 文本框,防止不需要的正则表达式模式字符
在PowerShell中,我一直在尝试不同的方法来从WinForms文本框中删除除我需要的模式之外的所有字符,但我无法为我所追求的问题提出更好的解决方案;我正在学习正则表达式,需要一些指导。这对我来说感觉很基本,但我觉得我错过了一些明显的东西。我正在使用文本框的 TextChanged 事件来防止输入非法字符,并且我有(感觉像是)一个臃肿的解决方案。
目标:
- 允许用户输入一个前导美元符号,后跟
[A-V0-9]
中最多 6 个字符- 如果未键入
$
,则键入的第一个合法字符应生成一个前导$
,后跟所述合法字符(键入A
将生成文本框中的$A
) - 如果首先输入非法字符,则文本框中不应生成前导
$
- 如果未键入
- 非法字符不会显示在文本框中
- 粘贴的文本将被处理/删除尽可能高效
- 删除的最后一个字符也将删除剩余的
$
- 如果文本框显示
$T
并且用户退格T
留下单个$
,则剩余的$
将也被删除
- 如果文本框显示
粘贴到文本框示例:
$$-#AZY$B9=%
将变为$AB9
Z))%ABC$YD144% $
会变成$ABCD14
$ZY%*#@!
在文本框中不产生任何内容
到目前为止我尝试过的事情:
- 使用
-split '^ \${1}'
和-replace '[^A-V0-9]'
以删除所有内容,然后将$
添加回来- 我真诚地道歉 - 我不记得此解决方案出现了哪些问题,但在某些情况下它的表现并不符合我的预期
- 使用
ForEach
循环检查字符串中的每个字符并替换那些确实存在的字符不匹配[A-V0-9]
然后插入$
- 这是我目前使用的臃肿解决方案
- 使用屏蔽文本框,但屏蔽字符串不接受范围字符
- 设置
$txtTextbox.MaxLength = 8
- 这会导致粘贴的文本无法得到正确处理
- 使用 regex101.com 进行大量谷歌搜索和摆弄正则表达式,并使用Lookarounds 等
- 使用布尔标志来确定单个前导
$
是否是首先手动键入/粘贴的,这样它就不会被删除它已键入(但保留在删除最后一个合法字符时清除文本框的能力,无论是使用退格键/删除/CTRL+X 进行剪切等)- 找到一个优雅的解决方案来解决这个悖论一直困扰着我(允许输入
$
,但如果它是文本框中唯一剩余的字符,则删除它)
- 找到一个优雅的解决方案来解决这个悖论一直困扰着我(允许输入
这是主要 到目前为止,我在文本框的 TextChanged 事件中找到了工作解决方案:
Clear-Host
Add-Type -AssemblyName System.Windows.Forms
$btnExit = New-Object System.Windows.Forms.Button -Property @{
Location = '50, 100'
Text = 'E&xit'
}
$frmTestForm = New-Object System.Windows.Forms.Form -Property @{
CancelButton = $btnExit
FormBorderStyle = 'Fixed3D'
MaximizeBox = $false
}
$txtTextbox = New-Object System.Windows.Forms.TextBox -Property @{
Location = '50, 50'
CharacterCasing = 'Upper'
}
$frmTestForm.Controls.Add($btnExit)
$frmTestForm.Controls.Add($txtTextbox)
$txtTextbox.Add_TextChanged({
$TempString = $txtTextbox.Text
foreach ($Character in $txtTextbox.Text.ToCharArray() )
{
# Working, but doesn't allow user to type a '$'
if (! ([regex]::IsMatch($Character, '^[A-V0-9]$' ) ))
{
$TempString = $TempString.Replace([string]$Character, "")
}
}
if ($TempString.Length -ne 0 -and $TempString[0] -ne '$')
{
# Add a leading '$' if there isn't one
$txtTextbox.Text = '$' + $TempString.Substring(0, [System.Math]::Min(6, $TempString.Length))
}
elseif ($txtTextbox.Text -eq '$')
{
# Deletes the $ automatically once the last remaining (legal) character is deleted.
# This also unfortunately prevents the user from manually typing a leading '$'
$txtTextbox.Clear()
}
else
{
# Prevent leading illegal characters from showing up/producing '$' and nothing else
$txtTextbox.Text = ''
}
$txtTextbox.Select($txtTextbox.Text.Length, 0)
})
$btnExit.Add_Click({
$frmTestForm.Close()
})
$frmTestForm.Add_Shown({
$txtTextbox.Select()
})
[System.Windows.Forms.Application]::Run($frmTestForm)
它不允许用户手动输入 $
如评论中所述,但这可能是我想要的如果允许的话愿意放弃会引入更多的膨胀。 归根结底,我的问题很简单:
正则表达式是否符合以下内容:$txtTextbox.Text = $txtTextbox.Text - 替换“除了 [^A-V0-9]{0,6}”之外的所有不是前导 $ 的内容'
更简单/更快/更多与一次评估每个角色相比,效率如何?该正则表达式会是什么样子?
预先感谢您的任何见解或(希望是建设性的)批评。
——保罗
In PowerShell I've been trying different ways of stripping out all characters from a WinForms textbox other than the pattern I need and I cannot come up with a better solution for what I'm after; I am learning regex and need some guidance. This feels basic to me but I feel like I'm missing something obvious. I'm using the textbox's TextChanged event to prevent illegal characters from being typed and I have (what feels like) a bloated solution.
Goal:
- User allowed to type a single leading dollar sign followed by up to 6 chars from
[A-V0-9]
- If no
$
is typed, the first legal character typed should produce a leading$
followed by said legal character (typingA
will produce$A
in the textbox) - If an illegal character is typed first, no leading
$
should be produced in the textbox
- If no
- Illegal characters won't show up in the textbox
- Pasted text is processed/stripped as efficiently as possible
- The last character deleted will also delete the remaining
$
- If textbox shows
$T
and user backspaces theT
leaving a single$
, the remaining$
will also be deleted
- If textbox shows
Pasting into the textbox examples:
$$-#AZY$B9=%
would become$AB9
Z))%ABC$YD144%$
would become$ABCD14
$ZY%*#@!
produces nothing in the textbox
Things I've tried so far:
- Using
-split '^\${1}'
and-replace '[^A-V0-9]'
to strip out everything out, then adding the$
back in- I sincerely apologize - I cannot remember what issues surfaced from this solution, but it didn't behave the way I expected in certain circumstances
- Using a
ForEach
loop to inspect each character in the string and replace those that do not match[A-V0-9]
then inserting a$
afterwards- This is the bloated solution I'm currently using
- Using a masked textbox, but the mask string doesn't accept a range of characters
- Setting
$txtTextbox.MaxLength = 8
- This prevents pasted text from being processed appropriately
- Quite a bit of Googling and fiddling with regexes, using regex101.com, playing with lookarounds etc
- Using a boolean flag to determine whether or not a single leading
$
was manually typed/pasted in the first place so it doesn't get deleted as soon as it's typed (yet retain the ability to clear the textbox upon the last legal character being deleted whether using Backspace/Delete/CTRL+X to cut etc)- Finding an elegant solution to this paradox is evading me (allow
$
to be typed but delete$
if it's the only remaining character in the textbox)
- Finding an elegant solution to this paradox is evading me (allow
This is the mostly working solution I have thus far in the textbox's TextChanged event:
Clear-Host
Add-Type -AssemblyName System.Windows.Forms
$btnExit = New-Object System.Windows.Forms.Button -Property @{
Location = '50, 100'
Text = 'E&xit'
}
$frmTestForm = New-Object System.Windows.Forms.Form -Property @{
CancelButton = $btnExit
FormBorderStyle = 'Fixed3D'
MaximizeBox = $false
}
$txtTextbox = New-Object System.Windows.Forms.TextBox -Property @{
Location = '50, 50'
CharacterCasing = 'Upper'
}
$frmTestForm.Controls.Add($btnExit)
$frmTestForm.Controls.Add($txtTextbox)
$txtTextbox.Add_TextChanged({
$TempString = $txtTextbox.Text
foreach ($Character in $txtTextbox.Text.ToCharArray() )
{
# Working, but doesn't allow user to type a '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
if (! ([regex]::IsMatch($Character, '^[A-V0-9]
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
) ))
{
$TempString = $TempString.Replace([string]$Character, "")
}
}
if ($TempString.Length -ne 0 -and $TempString[0] -ne '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
)
{
# Add a leading '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
if there isn't one
$txtTextbox.Text = '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
+ $TempString.Substring(0, [System.Math]::Min(6, $TempString.Length))
}
elseif ($txtTextbox.Text -eq '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
)
{
# Deletes the $ automatically once the last remaining (legal) character is deleted.
# This also unfortunately prevents the user from manually typing a leading '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
$txtTextbox.Clear()
}
else
{
# Prevent leading illegal characters from showing up/producing '
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:
$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
and nothing else
$txtTextbox.Text = ''
}
$txtTextbox.Select($txtTextbox.Text.Length, 0)
})
$btnExit.Add_Click({
$frmTestForm.Close()
})
$frmTestForm.Add_Shown({
$txtTextbox.Select()
})
[System.Windows.Forms.Application]::Run($frmTestForm)
It doesn't allow the user to manually type in a $
as noted in the comments, but that might be something I'm willing to give up if allowing this would introduce a lot more bloat.
At the end of the day, my question is simply:
Would a regex that's along the lines of:$txtTextbox.Text = $txtTextbox.Text -replace 'everything that isn't a leading $ in addition to [^A-V0-9]{0,6}'
be simpler/faster/more efficient compared to evaluating each character one at a time? What would that regex look like?
Thank you in advance for any insight or (hopefully constructive) criticism.
-Paul
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
使用你的测试字符串,我想出了这个:
Using your test strings , I came up with this: