假设字符串如下:
aaa bbb ccc
bbb aaa ccc
我想匹配的是aaa
,但不要在字符串开头匹配。我试图通过这样做来否定它:
[^^]aaa
但我不认为这是正确的。使用preg_replace
。
aaa bbb ccc
bbb aaa ccc
我想匹配的是aaa
,但不要在字符串开头匹配。我试图通过这样做来否定它:
[^^]aaa
但我不认为这是正确的。使用preg_replace
。
(?<!^)aaa
aaa
。只需用括号括起来? - StackOverflowNewbie[^\n]aaa
也可以完成任务(对我来说已经完成了),而且更简单,因此在没有可用的后顾断言时可以使用。 - polynomial_donutgsub()
进行此操作,只需设置perl = T
选项即可。 - Brian D由于我通过谷歌搜索来到这里,并且对不使用lookbehind的解决方案很感兴趣,这是我的建议。
[^^]aaa
模式匹配一个字符,除了^
之外,并且在字符串中的任何位置匹配3个a
s。 [^...]
是一个否定字符类,其中^
不被视为特殊字符。请注意,紧接在[
后面的第一个^
是特殊的,因为它表示否定,而第二个则只是字面上的插入符号。
因此,[...]
内部不能有^
表示字符串的开头。
解决方法是使用任何负面环视,以下两种方法都可以:
(?<!^)aaa
并且有一个预测:
(?!^)aaa
为什么前瞻也能起作用呢?前瞻是零宽度断言,而锚点也是零宽度的,它们不会消耗任何文本。简单来说,(?<!^)
检查当前位置左侧是否没有紧接着字符串开头的位置,(?!^)
则检查当前位置右侧是否没有紧接着字符串开头的位置。这两个表达式都是在检查同一些位置,所以两者都能正常工作。
(?<!^)
,但是在遵循ES5标准和旧的JS环境(包括IE)的VBA中仍然可以使用(?!^)
。 - Wiktor Stribiżew如果你不想使用回顾后发断言,那么可以使用这个正则表达式:
/.(aaa)/
并使用匹配组#1
。
aaa
。例如,对于字符串xaaaaaa
,只会有一个匹配。 - Black Mantha\K
。有趣。aaa
,然后回溯查找字符串锚点的开头。\K
模式进行比较。s
模式修饰符,以防止前导字符可能是换行符(.
通常无法匹配)。我只是想提前考虑到可能存在的特殊情况。\K
都胜过了其他技术。 | `~.\Kaaa~s` | `~.+?\Kaaa~s` | `(?<!^)aaa` | `(?!^)aaa` | `.(aaa)` |
--------------|-------------|---------------|-------------|------------|----------|
`aaa bbb ccc` | 12 steps | 67 steps | 8 steps | 8 steps | 16 steps |
--------------|-------------|---------------|-------------|------------|----------|
`bbb aaa ccc` | 15 steps | 12 steps | 6 steps | 6 steps | 12 steps |
if (strpos($haystack, 'aaa')) {
// 'aaa' is "truthy"
// 'aaa' is found and not positioned at offset zero
}
aaa bbb ccc
bbb aaa ccc
([^^])aaa
replace by:
$1zzz
aaa bbb ccc
bbb zzz ccc
aaa
吗?用什么替换它? - Explosion Pills