Regex 正则表达式:匹配模式,只要它是';这不是一开始

Regex 正则表达式:匹配模式,只要它是';这不是一开始,regex,regex-negation,Regex,Regex Negation,假设以下字符串: aaa bbb ccc bbb aaa ccc 我想匹配aaa,只要它不在字符串的开头。我试图通过这样做来否定它: [^^]aaa 但我认为这是不对的。使用preg\u replace可以使用“向后看”来确保它不在开头(?如果不想使用lookback,请使用以下正则表达式: /.(aaa)/ 并使用匹配组#1这将有助于找到您要查找的内容: ( 使用中的示例:因为我是通过谷歌搜索来到这里的,并且对一个不使用lookback的解决方案感兴趣,所以这里是我的2美分 模式匹配除^

假设以下字符串:

aaa bbb ccc
bbb aaa ccc
我想匹配
aaa
,只要它不在字符串的开头。我试图通过这样做来否定它:

[^^]aaa

但我认为这是不对的。使用
preg\u replace

可以使用“向后看”来确保它不在开头<代码>(?

如果不想使用lookback,请使用以下正则表达式:

/.(aaa)/

并使用
匹配组#1

这将有助于找到您要查找的内容:


使用中的示例:

因为我是通过谷歌搜索来到这里的,并且对一个不使用lookback的解决方案感兴趣,所以这里是我的2美分

模式匹配除
^
以外的字符,然后在字符串中的任何位置匹配3个
a
[^…]
是一个非特殊字符,其中
^
不被视为特殊字符。请注意
后面的第一个
^
[
是特殊的,因为它表示否定,而第二个符号只是一个文字插入符号

因此,
^
不能位于
[…]
内以表示字符串的开头

一种解决方案是使用任何负面环视,这两种方法同样有效:

(?<!^)aaa

为什么lookahead也能工作?是零宽度断言,锚也是零宽度-它们不消耗文本。从字面上说,
(?检查当前位置左侧是否没有字符串位置的开始,
(!^)
检查当前位置右侧是否没有字符串起始位置。正在检查相同的位置,这就是为什么两者都能正常工作的原因。

这种情况是我第一次看到lookarounds优于
\K
。很有趣

通常,捕获组和查找需要额外的步骤。但是由于此任务的性质,正则表达式引擎可以在搜索
aaa
时更快地导航字符串,然后回过头来查找字符串锚点的开始

我将添加几个
\K
模式进行比较

我正在使用
s
模式修饰符,以防主角可能是换行符(通常情况下,
不会匹配)。我只是想我会添加此考虑,以先发制人地解决可能出现的边缘情况

同样,这是一个很有启发性的场景,因为在我处理的所有其他regex案例中,
\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 |

我来这里是想看看re2引擎的解决方案,谷歌电子表格使用,它不支持lookarounds。 但是这里的答案让我想到了使用下面的方法。 我不明白为什么我要被抓获的团队取代,但无论如何,这是可行的

aaa bbb ccc
bbb aaa ccc

替换为:

$1zzz
在以下方面:

aaa bbb ccc
bbb zzz ccc


无论如何要否定位置断言?我仍然需要捕获
aaa
。只需用括号括起来?对于JavaScript,只使用(?^)aaa
[^\n]aaa
也应该做这项工作(为我做了这项工作),并且更简单/因此可以在没有lookbehind可用时使用。如果您在R中使用
gsub()
,如果您设置
perl=T
选项,它就可以工作了。您是否只匹配
aaa
?将其替换为什么?感谢前瞻选项,因为Javascript还不支持向后看。ECMAScript 2018+中已经引入了向后看支持,因此您可以使用
(?)在Node.JS和Chrome中,但是
(?!^)
在遵循ES5标准的VBA和旧版JS环境(包括IE)中仍然很好。Lookbehinds仅在Chrome 62+和Opera 49+中受支持()这是最好的答案,因为它也适用于regexp的其他方言。但是,除非您的regex引擎支持重叠匹配,否则它将不会相互匹配多次出现的
aaa
xaaaaaa
将只有一次匹配。有关在regex101.com中检查regex模式效率的有用建议。
if (strpos($haystack, 'aaa')) {
    // 'aaa' is "truthy"
    // 'aaa' is found and not positioned at offset zero
}
([^^])aaa
$1zzz