powershell Select-String:仅匹配前面没有 * 字符的字符串

2fjabf4q  于 2024-01-08  发布在  Shell
关注(0)|答案(2)|浏览(191)

我在Powershell脚本中有这样一行:
第一个月
$holidays是一个文本文件,我有一些日期:

2023-09-04
2023-11-23
*2023-11-24
2023-12-25

字符串
$datestr是今天日期:2023-11-23
为什么负的lookbehind模式在上面的行中不起作用?
我只是想排除(不匹配)所有以 * 开头的日期
我认为在负向后看中有些地方是错误的,因为这条线:

if (Select-String -Path "$holidays" -Pattern $datestr -SimpleMatch -Quiet)


工作完美-->结果是真实的
第一行的结果为false

8ljdwjyq

8ljdwjyq1#

让我用一些背景信息补充**Santiago Squarzon's helpful answer**:

  • Select-String将其**-Pattern**参数默认解释为regexes *。
  • 只有当你想要 literal 子串匹配时,你才需要**-SimpleMatch**。
  • 在这两种情况下,默认情况下匹配不区分大小写(PowerShell通常如此);使用
    **-CaseSensitive**根据需要。
  • -SimpleMatch不要与这些其他开关混淆-这些开关与-Pattern参数是否被解释为正则表达式或文字字符串无关:
    -Raw-仅在PowerShell (Core) 7+中可用-按原样发出匹配的输入字符串(行),而不是在Microsoft.PowerShell.Commands.MatchInfo示例中报告它们的默认行为,Microsoft.PowerShell.Commands.MatchInfo示例用关于匹配的 * 元数据 * 补充匹配的输入字符串。
    -AllMatches(与-Raw-SimpleMatch不兼容)要求在 * 每个输入字符串(行) 上,查找模式的 * 所有 * 匹配项,而不仅仅是 * 第一个匹配项。
  • 注意事项:-Raw只发出 * 字符串 *,所以根据定义,没有关于 * 每个字符串的哪些部分匹配 * 的信息可以报告;类似地,-SimpleMatch没有记录这样的信息,即使有 * 多个 * -Pattern参数可能会感兴趣;另外,不幸的是,从v7.4.0开始,-SimpleMatch-AllMatches的组合被悄悄地接受了,尽管-AllMatches没有任何效果-请参阅GitHub issue #11091
  • MatchInfo对象的.Matches属性是System.Text.RegularExpressions.Match对象的 * 集合 *,以支持-AllMatches。如果没有后者,.Matches集合只有 * 一个 * 条目。
    **-List**一旦找到匹配的字符串,就停止处理进一步的输入字符串,并仅为该输入输出MatchInfo示例(或-Raw[string]示例),即每个输入文件最多输出 * 一个 *-这可能是一个重要的性能改进。
    ***-Quiet**的行为类似于-List,只是它发出的不是MatchInfo示例,而是$true,即一个表示找到匹配的抽象指示符。
  • 注意事项:虽然如果没有找到匹配项,$false会被发送,但在PowerShell(Core)7.4.0中情况并非如此;相反,* 没有输出 *;请参阅GitHub issue#16681

也就是说,在隐含的布尔上下文中,no output 等同于$false-请参阅概念about_Booleans帮助主题

f4t66c6m

f4t66c6m2#

正如注解中所解释的,当使用-SimpleMatch时,小程序不使用regex
指示小工具使用简单匹配而不是正则表达式匹配。在简单匹配中,Select-String在输入中搜索Pattern参数中的文本。它不会将Pattern参数的值解释为正则表达式语句。
在你的例子中,小程序正在寻找一个文字(?<!\*)2023-11-23,而不是前面没有*2023-11-23

$datestr = '2023-11-23'
'2023-11-23' | Select-String -Pattern "(?<!\*)$datestr" -SimpleMatch -Quiet # No output
'2023-11-23' | Select-String -Pattern "(?<!\*)$datestr" -Quiet              # True

字符串
总而言之,你的情况应该是:

if (Select-String -Path $holidays -Pattern "(?<!\*)$datestr" -Quiet) {
    # do stuff
}

相关问题