在我的主目录中,我有一个文件夹drupal-6.14,其中包含drupal平台。
在这个目录中,我使用以下命令:
find drupal-6.14 -type f -iname '*' | grep -P 'drupal-6.14/(?!sites(?!/all|/default)).*' | xargs tar -czf drupal-6.14.tar.gz
此命令的作用是gzip文件夹drupal-6.14,不包括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 regex手册、其他类似http://www.regular-expressions.info/lookaround.html的页面等等,但我从未真正对它们有过深入的了解。
有人能解释一下,这是如何工作的,也许能提供一些类似的例子来做类似的事情?
--更新一个:
关于Andomar的回答:双否定的lookahead是否可以更简洁地表示为一个正的lookahead语句:
即:
'drupal-6.14/(?!sites(?!/all|/default)).*'
相当于:
'drupal-6.14/(?=sites(?:/all|/default)).*'
???
——更新二:
根据“andomar”和“alan moore”的说法,你不能把双负展望换成正展望。
Lookarounds可以嵌套。
因此,这个regex匹配“drupal-6.14/”即不后跟“sites”即不后跟“/all”或“/default”。
困惑?使用不同的词,我们可以说它与“drupal-6.14/”匹配,即不是紧跟“sites”,除非后面紧跟“/all”或“/default”
一个否定的展望说,在这个位置,下面的正则表达式不能匹配。
让我们举一个简单的例子:
最后一个例子是一个双反:它允许一个
b
后跟一个c
。嵌套的负lookahead变为正lookahead:Thec
应该存在。在每个示例中,只有
a
匹配。向前看只是一个条件,不会添加到匹配的文本中。如果您像这样修改正则表达式:
…然后它将匹配所有包含
drupal-6.14/
后跟sites
后跟的输入,而不是/all
或/default
。例如:将
?=
更改为?!
以匹配原始regex只会使这些匹配无效:所以,这仅仅意味着
drupal-6.14/
现在不能后面跟着sites
后面跟着除了/all
或/default
之外的任何东西。现在,这些输入将满足regex:但是,从其他一些答案(也可能是您的问题)中可能不明显的是,您的regex还允许其他输入,其中
drupal-6.14/
后面还有sites
以外的任何内容。例如:结论:因此,您的regex基本上说要包含
drupal-6.14
的所有子目录,除了sites
的那些子目录,它们的名称以all
或default
以外的任何子目录。相关问题 更多 >
编程相关推荐