通过一些复杂的测试,我最终可能发现了一条捷径。
PowerShell中的lookbehind应该使用<=
语法,当在PowerShell中搜索lookbehind时,该语法在其他多个地方被引用,例如this Microsoft blog。
以这个简单的例子Regex:
(?〉^[^x]*)$
- )开始向后看
- ^[^x]* 测试字符 * x * 是否从字符串开头开始就不存在
- )关闭后视
- $固定行的结尾
当我测试它时:
'sample = x' -match '(?>^[^x]*)$'
False
'sample = ' -match '(?>^[^x]*)$'
True
第一个块返回false:lookbehind不匹配没有 * x * 的字符串。
第二个块返回true:lookbehind匹配没有 * x * 的字符串。
好像管用了!
现在,如果我尝试使用<=
语法:
一个二个一个一个
它有相同的行为。
这是PowerShell中RegEx查找的"捷径"吗?或者>
为什么能工作?
435|PS(7.2.1) C:\Users\User\Documents [230211-15:03:27]> $PSVersionTable
Name Value
---- -----
PSVersion 7.2.1
PSEdition Core
GitCommitId 7.2.1
OS Microsoft Windows 10.0.22621
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
1条答案
按热度按时间unhi4e5o1#
(?<=…)
和(?>…)
用于不同的目的,只是在您的特定场景中 * 碰巧 * 工作相同;在您的方案中不需要 * 两者都不需要 *。'...' -notmatch 'x'
测试给定字符串是否包含'x'
的任何示例(如果 * 不是 *,则返回$true
)。您引用的两个分组构造用于不同的目的(包含的子表达式用下面的占位符
…
表示):(?<=…)
是一个(零宽度,正)后看Assert:(?<=…)
内部的子表达式;如果不匹配,则没有总体匹配;如果是,则不 * 捕获 *(包括在结果中)其匹配。(?>…)
是一个原子组,也称为 * 非回溯子表达式 *:(…)
-* 除了 * 它 * 从不回溯 *。(?<=^[^x]*)$
-带有 * lookbehindAssert * 的正则表达式如上所述,没有理由在使用lookbehind * assertion * 之后不使用 * capturing * 表达式,因为根据定义,您的正则表达式不会捕获任何内容(
$
本身就是一个 * assertion *)。因为你要匹配 * 整个字符串 , immediate * 的简化方式是根本不使用分组构造(但是请看下面的部分):
^[^x]*$
作为一种优化,如果您明确希望阻止默认情况下发生的捕获,请使用非捕获组
(?:…)
:(?:^[^x]*$)
(?>^[^x]*)$
-带有 * 原子组 * 的正则表达式由于您要匹配的是 * whole string *,所以没有理由使用 * atomic * 组,因为不需要防止回溯,所以这个正则表达式实际上与
(^[^x]*)$
相同,即常规捕获组(后面跟着$
)。如前所述,没有理由在这里"捕获"任何内容,因此
(?:^[^x]*$)
将防止这种情况。简而言之:
概念上最简单且最有效的解决方案是:
也就是说,您可以让
-notmatch
(PowerShell的-match
运算符的求反形式)查找(最多一个)x
,并对布尔结果求反,以便 * not * 查找任何x
返回$true
。换句话说:如果输入字符串中存在 * no *
x
,则测试成功。