$msg = 'http://www.bla.de'
$match = $msg -match '^(.*)".+?":(\S+)\s*(.*)$'
$match_linkalone = $msg -match '^(.*)(http://|https://)(\S+)\s*(.*)$'
$match
> False
$match_linkalone
> True
if($match -eq "True" -and $match_linkalone -eq "False")
{echo 'if';}
elseif($match_linkalone -eq "True" -and $match -eq "False")
{echo 'elif';}
else
{echo 'else';}
> else
但如果我这样做
$match = 'False'
$match_linkalone = 'True'
if($match -eq "True" -and $match_linkalone -eq "False")
{echo 'if';}
elseif($match_linkalone -eq "True" -and $match -eq "False")
{echo 'elif';}
else
{echo 'else';}
> elif
我真的不明白这个......
当$match = False
和$match_linkalone = True
通过-match
定义时,它应该会运行到我的elseif
语句中。但它会转到else
,我不知道为什么......但是当我手动将文本放入两个变量时,它可以工作。
我正在使用PowerShell
答案 0 :(得分:3)
您的变量$match
和$match_linkalone
包含布尔值,但您要将它们与字符串进行比较。在比较PowerShell automatically converts之类的第二个操作数与匹配第一个操作数的类型。转换为布尔值时,空字符串变为$false
,非空字符串变为$true
。
基本上你的表达式是这样评估的:
$match -eq "True" -and $match_linkalone -eq "False"
$false -eq $true -and $true -eq $true
$false -and $true
$false
将第二个操作数更改为布尔值:
if ($match -eq $true -and $match_linkalone -eq $false)
或(更好)完全删除比较,因为您的变量已包含布尔值:
if ($match -and -not $match_linkalone)
问题就会消失。
答案 1 :(得分:2)
首先,关于正则表达式的一些注释:
1)捕获组比非捕获组慢,因此使用例如除非您确实需要捕获群组,否则(?:.*)
而不是(.*)
更为理想。
2)http://|https://
等于https?://
。 PowerShell中也允许使用未转义的斜杠,但出于各种原因,我仍然使用\/
而不是/
,包括与regex101.com等工具的兼容性。
现在回答。当$foo
是一个布尔值(并且-match
运算符总是返回一个布尔值)时,使用像$foo -eq "True"
这样的结构是个糟糕的主意。并不是因为它不会起作用(你可以通过写$foo.ToString() -eq "true"
之类的东西来使它工作)但是因为它效率低,不可维护且容易出错。不要那样做!这就是你想要的:
$msg = 'http://www.bla.de'
$match = $msg -match '^(.*)".+?":(\S+)\s*(.*)$'
$match_linkalone = $msg -match '^(.*)(https?:\/\/)(\S+)\s*(.*)$'
if ( ($match) -and (! $match_linkalone) ) {
Write-Output 'if'
}
elseif ( ($match_linkalone) -and (! $match) ) {
Write-Output 'elif'
}
else {
Write-Output 'else'
}
输出:
elif