Powershell - 是否可以避免在字符串中找到字符串
Powershell - Is it possible to avoid finding a string inside a string
我正在尝试将基于字符串的变量与基于 .csv 的列表进行比较以确定该字符串是否存在。我忽略的是变量可能是其中一个项目列表的子字符串的可能性。
在下面的代码之前,我提示用户输入名字和姓氏,然后使用提供的信息执行以下操作以生成 8 个字符的用户名,然后对照列表进行检查查看该用户名是否可用或已被占用。
$LastName = $objTextBoxLN.text
$LastName = (Get-Culture).textinfo.totitlecase($LastName)
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()
Write-Host "Searching for Username Conflicts"
Write-Host
IF(select-string -Path "c:\Folder_X\userlist.csv" -pattern $UN)
{
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(6, $objTextBoxLN.text.Length))+$objTextBoxFN.text.Substring(0,2)
Write-Host "Conflict found! Username" $UN.ToLower() "generated using 6 characters from last name plus 2 characters from first name (Option 2)"
Write-Host
ELSE
{
Write-Host "No Conflicts Found. Username" $UN "generated using 7 characters from last name plus 1 character from first name (Option 1)"
Write-Host
}
所以如果在 Userlist.csv 我们有一个用户名列表:
- 史密斯
- 白
- 白维
等...
最终用户输入 "Harry Smit" 它将生成用户名 "smith" 然后 IF 语句将在列表中找到 "smith",在当前用户名 [=34] 中=] 并将用户名更新为 "smithhi" 但这不是我希望实现的行为,我希望它发现用户名 "smith" 不存在并且 return 原来用户名。
感谢任何人可以提供的任何帮助,希望有一个简单的解决方案。
由于每行都有一个,您可以使用正则表达式行开始和结束锚点来强制完全匹配。
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()
$UN = '^\s*{0}\s*$"' -f $UN
我建议从查询中获得更合理的输出。如果您可以获得干净的字段分隔符,则可以使用 import-csv
并且实际上只检查您感兴趣的列。
import-csv "c:\Folder_X\userlist.csv" -delimiter ' ' -Header @('un','f','l')
un f l
-- - -
"smithj" (John Smith)
"whitew" (Walter White)
"smith" (Harry Smit)
如果你真的不能改变你的输入...
select-string
能够匹配正则表达式。将您要扫描的用户名构建到与您输入的字段格式相匹配的正则表达式中。
select-string -Path "c:\Folder_X\userlist.csv" -Pattern "^$UN\b"
例如,这会查找锚定在行首并紧跟其后的单词边界的用户名。
我正在尝试将基于字符串的变量与基于 .csv 的列表进行比较以确定该字符串是否存在。我忽略的是变量可能是其中一个项目列表的子字符串的可能性。
在下面的代码之前,我提示用户输入名字和姓氏,然后使用提供的信息执行以下操作以生成 8 个字符的用户名,然后对照列表进行检查查看该用户名是否可用或已被占用。
$LastName = $objTextBoxLN.text
$LastName = (Get-Culture).textinfo.totitlecase($LastName)
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()
Write-Host "Searching for Username Conflicts"
Write-Host
IF(select-string -Path "c:\Folder_X\userlist.csv" -pattern $UN)
{
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(6, $objTextBoxLN.text.Length))+$objTextBoxFN.text.Substring(0,2)
Write-Host "Conflict found! Username" $UN.ToLower() "generated using 6 characters from last name plus 2 characters from first name (Option 2)"
Write-Host
ELSE
{
Write-Host "No Conflicts Found. Username" $UN "generated using 7 characters from last name plus 1 character from first name (Option 1)"
Write-Host
}
所以如果在 Userlist.csv 我们有一个用户名列表:
- 史密斯
- 白
- 白维
等...
最终用户输入 "Harry Smit" 它将生成用户名 "smith" 然后 IF 语句将在列表中找到 "smith",在当前用户名 [=34] 中=] 并将用户名更新为 "smithhi" 但这不是我希望实现的行为,我希望它发现用户名 "smith" 不存在并且 return 原来用户名。
感谢任何人可以提供的任何帮助,希望有一个简单的解决方案。
由于每行都有一个,您可以使用正则表达式行开始和结束锚点来强制完全匹配。
$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()
$UN = '^\s*{0}\s*$"' -f $UN
我建议从查询中获得更合理的输出。如果您可以获得干净的字段分隔符,则可以使用 import-csv
并且实际上只检查您感兴趣的列。
import-csv "c:\Folder_X\userlist.csv" -delimiter ' ' -Header @('un','f','l')
un f l
-- - -
"smithj" (John Smith)
"whitew" (Walter White)
"smith" (Harry Smit)
如果你真的不能改变你的输入...
select-string
能够匹配正则表达式。将您要扫描的用户名构建到与您输入的字段格式相匹配的正则表达式中。
select-string -Path "c:\Folder_X\userlist.csv" -Pattern "^$UN\b"
例如,这会查找锚定在行首并紧跟其后的单词边界的用户名。