2

我想要一个 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
  • 要求是仅 grep 具有类似数字IPS7且不以开头的 IPS 单词_

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

我该如何指定!不是_ 吗?

4

5 回答 5

4

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

使用glob, < ... >,这几乎是对 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 的方法。

于 2013-08-27T09:10:33.907 回答
2

使用\bregexp 运算符匹配单词边界:

\bIPS\d+$
于 2013-08-27T07:42:45.617 回答
1

您可以使用否定字符类:

[^_]IPS\d+$

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

于 2013-08-27T07:42:34.650 回答
0

在你之前添加这个regex它会寻找单词边界并且仍然不包含在之前的结果中IPS

(?<=\b)

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

(?<=\b)IPS\d+\d*$
于 2013-08-27T07:44:31.390 回答
0

只需要从IP开始捕获。

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

(^IPS\d+)$

于 2013-08-27T08:40:16.447 回答