【问题标题】:Perl Regex to Grep a word not starting with special character _Perl Regex to Grep一个不以特殊字符_开头的单词
【发布时间】:2013-08-27 17:10:33
【问题描述】:

我想要一个 perl 正则表达式从以下输出中 grep 一个单词:

Process Completed;Result= Volume in drive D has no label.

 Volume Serial Number is 328A-C899

 Directory of D:\Program

07/14/2013  12:09 PM    <DIR>          .
07/14/2013  12:09 PM    <DIR>          ..
06/16/2013  01:07 PM    <DIR>          IPS
07/14/2013  12:10 PM    <DIR>          IPS1
07/14/2013  12:12 PM    <DIR>          IPS2
07/14/2013  12:16 PM    <DIR>          IPS3
07/14/2013  01:50 PM    <DIR>          IPS4
07/14/2013  12:17 PM    <DIR>          IPS5
07/14/2013  12:17 PM    <DIR>          IPS6
07/14/2013  12:18 PM    <DIR>          IPS7
07/14/2013  12:18 PM    <DIR>          IPS8
06/16/2013  01:10 PM    <DIR>          IPSCommon
07/08/2013  12:32 PM    <DIR>          _IPS10
07/08/2013  12:32 PM    <DIR>          _IPS11
07/08/2013  12:32 PM    <DIR>          _IPS12
07/08/2013  12:32 PM    <DIR>          _IPS13
07/08/2013  12:32 PM    <DIR>          _IPS14
07/08/2013  12:57 PM    <DIR>          _IPS15
07/08/2013  12:32 PM    <DIR>          _IPS16
07/08/2013  03:38 PM    <DIR>          _IPS17
07/08/2013  12:32 PM    <DIR>          _IPS18
07/08/2013  12:32 PM    <DIR>          _IPS9
               0 File(s)              0 bytes
              22 Dir(s)  770,968,162,304 bytes free
  • 要求仅对具有IPS7 之类的数字且不以_ 开头的IPS 单词进行grep

我使用了以下正则表达式 IPS\d+\d*$ 但这也会 grep 以 _ 开头的单词

如何指定!不是_

【问题讨论】:

  • @Zaid 我们在打编辑战吗?我把所有的双倍行距都拿出来了,你把它放回去!
  • @Barmar :看起来我们遇到了竞争条件 :)。无论如何,它不会影响问题或答案。

标签: regex perl


【解决方案1】:

您正在尝试解析 Windows dir 命令的输出,我认为这是您尝试列出目录中的文件。您应该知道这不是实现此目的的好方法,我将向您展示一些替代方法。正则表达式的答案已经给出,所以我不会打扰。

使用 glob&lt; ... &gt;,这几乎是对 shell 如何扩展通配符的模拟。

my @ips = grep /^IPS\d+/,      # only IPS with number
          grep -d,             # only directories
          <D:/Program/IPS*>;   # list IPS file in the target dir

使用opendir

opendir my $dh, "D:/Program" or die $!;
my @ips = grep /^IPS\d+/, readdir($dh);   
closedir $dh;

使用File::Find。请注意,此选项是递归的(也会列出子目录中的文件):

use File::Find;    # core module in Perl 5
my @ips;
find(sub { push @ips, $File::Find::name if /^IPS\d+/ }, "D:/Program");

每种方法都有自己的优势。在您的情况下,使用最相似的方法是最上面的方法,即使用 glob 的方法。

【讨论】:

    【解决方案2】:

    使用\b 正则表达式运算符来匹配单词边界:

    \bIPS\d+$
    

    【讨论】:

      【解决方案3】:

      您可以使用否定字符类:

      [^_]IPS\d+$
      

      请注意,原始正则表达式中的第二个\d 是多余的,因为\d+ 将是贪婪的。

      【讨论】:

        【解决方案4】:

        在您的regex 之前添加它,它将查找单词边界,但仍然不包含在IPS 之前的结果中

        (?<=\b)
        

        所以你的最终正则表达式看起来像

        (?<=\b)IPS\d+\d*$
        

        【讨论】:

        • \b 已经是一个零宽度的断言,因此不必将其放入lookbehind 中。
        【解决方案5】:

        只需要从IP开始捕获。

        请使用下面的正则表达式。

        (^IPS\d+)$

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-09-13
          • 2014-10-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-29
          相关资源
          最近更新 更多