regex - 正则表达式负向前瞻

标签 regex regex-lookarounds

在我的主目录中,有一个包含 Drupal 平台的文件夹 drupal-6.14。

在此目录中,我使用以下命令:

find drupal-6.14 -type f -iname '*' | grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*' | xargs tar -czf drupal-6.14.tar.gz

此命令的作用是对文件夹drupal-6.14进行gzip压缩,排除drupal-6.14/sites/的所有子文件夹除了sites/all和sites/default ,其中包括。

我的问题是关于正则表达式:

grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*'

表达式可以排除我想要排除的所有文件夹,但我不太明白为什么。

这是使用正则表达式来完成的常见任务

Match all strings, except those that don't contain subpattern x. Or in other words, negating a subpattern.

我(认为)我理解解决这些问题的一般策略是使用否定前瞻,但我从未令人满意地理解积极和否定前瞻(前方/后方)的工作原理。

这些年来,我读过很多关于它们的网站。 PHP 和 Python 正则表达式手册,其他页面如 http://www.regular-expressions.info/lookaround.html等等,但我从来没有真正对它们有过深入的了解。

有人可以解释一下这是如何工作的,并可能提供一些可以做类似事情的类似示例吗?

--更新一:

关于 Andomar 的回应:双重否定前瞻能否更简洁地表达为单个肯定前瞻语句:

即是:

'drupal-6.14/(?!sites(?!/all|/default)).*'

相当于:

'drupal-6.14/(?=sites(?:/all|/default)).*'

???

--更新二:

根据@andomar和@alan moore - 你不能将双负前瞻互换为正前瞻。

最佳答案

负向前瞻表示,在此位置,以下正则表达式无法匹配。

让我们举一个简单的例子:

a(?!b(?!c))

a      Match: (?!b) succeeds
ac     Match: (?!b) succeeds
ab     No match: (?!b(?!c)) fails
abe    No match: (?!b(?!c)) fails
abc    Match: (?!b(?!c)) succeeds

最后一个例子是一个双重否定:它允许b后面跟着c。嵌套的负向先行变为正向先行:c 应该存在。

在每个示例中,仅匹配 a。前瞻只是一个条件,不会添加到匹配的文本中。

关于regex - 正则表达式负向前瞻,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1749437/

相关文章:

javascript - 匹配给定的正则表达式,除非给定的单词存在(lookahead 或lookbehind)

java - 正则表达式中的负向前瞻匹配所有接受特定字符的内容

regex - 前瞻 : not working with `.+?` 之前的惰性正则表达式

php - 正则表达式获取两个字符串 '$' 和 ';' 之间且前面不带 '//' 的任何内容

regex - 使用函数替换正则表达式子匹配

java - 如何发现包含转义字符的正则表达式?

javascript - 如何从 json/字符串中删除特殊字符和特定单词?

python - 用于在逗号分隔的字符串中查找 float 的正则表达式

java - 正则表达式 - 在句子中的单位说明符之前选择一个数字

java - Guava Splitter 到键值映射,字符串中包含拆分字符