首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >perl regex -如何匹配不以(\S*//S*)开头的foobar

perl regex -如何匹配不以(\S*//S*)开头的foobar
EN

Unix & Linux用户
提问于 2019-06-16 07:16:26
回答 3查看 1.7K关注 0票数 0

基本上,我想在未注释的行上找到foobar,例如:

代码语言:javascript
复制
// foobar      # do not match me
 foobar        # match me
 otherfoobar   # do not match me

为了匹配注释行,我使用以下代码:^(\s*//\s*)\bfoobar\b.*$

如何匹配未注释的行?

注:

为了避免不必要的努力,请将答案限制在“^.$”。这必须完全在发送给perl进行匹配的字符串中完成。

另外,必须像在\bfoobar\b中那样匹配foobar。

最后,不应在\bfoobar\b之前加上空格或注释签名。

EN

回答 3

Unix & Linux用户

回答已采纳

发布于 2019-06-16 15:55:15

我认为否定的问题不应过于复杂。

比如说,我想拒绝这几句话:

代码语言:javascript
复制
"^(\s*//\s*).*(\bfoobar\b).*$"

即。在开始时,将注释签名'//'放在空格中的任何位置,然后是包含'foobar'作为一个完整单词的任何内容(包括括号以表示清楚性)。

为了否定这一点,我们做了:

代码语言:javascript
复制
"^(?!\s*//\s*).*(\bfoobar\b).*$"

我们只需将(\s*//\s*)替换为(?!\s*//\s*)

这忽略了任何在空格中任何地方都有注释签名'//'的东西,在开始时,后面跟着我们的模式。

结果:

代码语言:javascript
复制
  // foobar will not be matched
  // whatever foobar will not be matched
  foobar will be matched
  whatever foobar will be matched
  whateverfoobar will not be matched

<#>注意:您可以通过在设置.*之前更改(\bfoobar...来进一步优化。

我可以做"^(?!\s*//\s*)\s*(\bfoobar\b).*$"

代码语言:javascript
复制
  foobar will be matched
  whatever foobar will **NOT** be matched

警告:如果您曾经用一些任意字符串(如'foobar' )替换'${foobar}',并且尝试了上面的操作,那么它将失败。原因是因为你通常的'foobar‘是由单词组成的,而现在(\bfoobar\b)将无法匹配它。在这种情况下,必须删除\b

票数 1
EN

Unix & Linux用户

发布于 2019-06-16 21:29:19

foobar的右侧找不到的//可以表示为:

代码语言:javascript
复制
^(?:(?!//).)*\bfoobar\b

这是一个0或多个(*)字符(.)的序列,每个字符都不是在//序列((?!//))的开头,后面是由单词边界分隔的foobar

票数 2
EN

Unix & Linux用户

发布于 2019-06-16 16:56:49

如果您使用的是Perl (语言),而不是使用与Perl兼容的regexes的某个工具,那么就没有理由将自己限制在一个regex上。

类似这样的内容将与未注释的行相匹配:

代码语言:javascript
复制
$ perl -ne 'print if not m,^\s*//, and /\bfoobar\b/' < file.txt 
 foobar        # match me

即使使用其他实用程序或非Perl regexes,也可能更容易使用多个regexes:

代码语言:javascript
复制
$ < file.txt grep -ve '//' | grep '\'
 foobar        # match me

如果您被限制在单个Perl regex上,那么应该可以这样做:

代码语言:javascript
复制
grep -P '^\s*+(?!//).*\bfoobar\b.*\s*+是一个“占有”表情,它匹配所有的前导空格,并且不放过它们。然后,(?!//)检查前面空格后面的内容是否是注释标记,最后,我们在行的任何地方查找单词分叉中的foobar。(如果在没有拥有限定符的情况下匹配了空白,regex引擎可能会退出前面的空格,并在错误的位置检查注释标记,从而导致注释行被匹配。)测试数据:$ cat file.txt
 // foobar        # do not match
 foobar           # 1st match
otherfoobar       # do not match
something foobar  # 2nd and final match
$ grep -P '^\s*+(?!//).*\bfoobar\b.* file.txtD3是一个C4,它匹配所有的前导空格,并且不放过它们。然后,D5检查前面空格后面的内容是否是注释标记,最后,我们在行的任何地方查找单词分叉中的D6。(如果在没有拥有限定符的情况下匹配了空白,regex引擎可能会退出前面的空格,并在错误的位置检查注释标记,从而导致注释行被匹配。)测试数据:A7 file.txt
 foobar           # 1st match
something foobar  # 2nd and final match

file.txt

D3是一个C4,它匹配所有的前导空格,并且不放过它们。然后,D5检查前面空格后面的内容是否是注释标记,最后,我们在行的任何地方查找单词分叉中的D6

(如果在没有拥有限定符的情况下匹配了空白,regex引擎可能会退出前面的空格,并在错误的位置检查注释标记,从而导致注释行被匹配。)

测试数据:

A7

票数 1
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/525229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档