AdminOfThing's answer 很有帮助,但我发现自己希望以不同的方式构图。
解决方案:
使用 .NET 框架:
.NET String.IndexOf() 方法执行文字子字符串搜索,并返回输入字符串中子字符串开头的字符的基于0 的索引(如果子字符串不能,则返回-1根本找不到):
PS> 0 -eq 'foo\bar'.IndexOf('foo\')
True
请注意,与 PowerShell 的运算符不同,上述操作符默认区分大小写,但您可以通过附加参数更改为不区分大小写的行为:
PS> 0 -eq 'foo\bar'.IndexOf('FOO\', [System.StringComparison]::InvariantCultureIgnoreCase)
True
请注意,PowerShell 在许多(但不是全部)上下文中使用 invariant 而不是当前区域性,例如使用运算符 -eq、-contains、-in 和 switch声明。
如果不需要锚你的子字符串搜索,即如果你只想知道输入字符串中是否包含子字符串somewhere,你可以使用String.Contains():
# Substring is present, but not at the start
# Note: matching is case-SENSITIVE.
PS> 'foo\bar'.Contains('oo\')
True
警告:在 Windows PowerShell 中,.Contains()总是区分大小写。在 PowerShell (Core) 7+ 中,提供了一个不区分大小写的额外重载(例如,
'FOO\BAR'.Contains('oo\', 'InvariantCultureIgnoreCase'))
使用-match 运算符:
虽然-match 确实隐式执行substring 匹配,但它是基于regex (regular expression) 而不是文字字符串。
-match 默认执行大小写-不敏感匹配;使用-cmatch 变体区分大小写。
这意味着您可以方便地使用输入起始锚点^,以确保搜索表达式仅在输入字符串的开始处匹配。
相反,为了让您的搜索字符串在您的正则表达式中被视为 literal 字符串,您必须 \-escape 其中的任何正则表达式 元字符(字符具有特殊含义的)在正则表达式中。
由于\ 本身就是一个元字符,它也必须被转义,即\\。
在字符串文字中,您可以手动进行转义:
# Manual escaping: \ is doubled.
# Note the ^ to anchor matching at the start.
PS> 'foo\bar' -match '^foo\\'
True
以编程方式,当字符串作为变量时,必须使用[regex]::Escape()方法:
# Programmatic escaping via [regex]::Escape()
# Note the ^ to anchor matching at the start.
PS> $s = 'foo\'; 'foo\bar' -match ('^' + [regex]::Escape($s))
True
使用-like 运算符:
与-match 不同,-like 执行 full-string 匹配,并且基于 wildcard expressions(在 Unix 世界中也称为 globs)进行匹配;虽然与正则表达式关系很远,但它们使用更简单、不兼容的语法(并且功能远没有那么强大)。
-like 默认执行大小写-不敏感匹配;使用-clike 变体区分大小写。
通配符只有 3 个基本结构,因此只有 3 个元字符:?(匹配单个字符)、*(匹配任意数量的字符,包括无字符)和 [(开始匹配单个字符的字符集或范围。例如,[a-z] 或 [45])。
在最简单的情况下,您只需将* 附加到您的搜索字符串,以查看它是否与输入字符串的开头匹配:
# OK, because 'foo\' contains none of: ? * [
PS> 'foo\bar' -like 'foo\*'
True
# With a variable, using an expandable string:
PS> $s = 'foo\'; 'foo\bar' -like "$s*"
True
不过,与-match 一样,可能需要进行程序转义,这需要调用[WildcardPattern]::Escape():
PS> $s = 'foo['; 'foo[bar' -like ([WildcardPattern]::Escape($s) + '*')
True