Regex perl-如何使用正则表达式捕获空单元格

Regex perl-如何使用正则表达式捕获空单元格,regex,perl,Regex,Perl,输出: 我的正则表达式: id | status | name | cluster | ip | mac | roles | pending_roles | online ---|----------|------------------|---------|-------------|-------------------|-------|-----------------|------- 11 | discover

输出:

我的正则表达式:

id | status   | name             | cluster | ip          | mac               | roles | pending_roles   | online
---|----------|------------------|---------|-------------|-------------------|-------|-----------------|-------
11 | discover | Untitled (9a:3a) | 12      | 10.20.0.144 | c8:1f:66:ce:9a:3a |       | cinder          | True
12 | discover | Untitled (9f:8d) | 12      | 10.20.0.186 | c8:1f:66:ce:9f:8d |       | cinder, compute | True
10 | discover | Untitled (c7:f3) | None    | 10.20.0.214 | c8:1f:66:ce:c7:f3 |       |                 | True
13 | discover | Untitled (9f:3d) | None    | 10.20.0.233 | c8:1f:66:ce:9f:3d |       |                 | True
8  | discover | Untitled (74:8e) | 12      | 10.20.0.184 | c8:1f:66:ce:74:8e |       | controller      | True
14 | discover | Untitled (75:4b) | None    | 10.20.0.185 | c8:1f:66:ce:75:4b |       |                 | True
9  | discover | Untitled (76:23) | None    | 10.20.0.213 | c8:1f:66:ce:76:23 |       |                 | True
但是抓不到空的牢房!我试过很多方法

行示例:

\d+)\s+\|\s+(\w+)\s+\|\s+\w+\s+\((\S+)\)\s+\|\s+(\d+)\s+\|\s+(\S+)\s+\|\s+(\S+)\s+\|(.*?)\|(.*?)\|\s+(\w+)

不要试图将结构化数据视为非结构化行。您有管道分隔的数据,所以将其作为管道分隔的数据进行分析,然后检查所分析内容

请注意,我在单个单元格上使用正则表达式(
/^\s*$/
查看它是否都是空白),但不是在每一行上

下面是一个例子:

13 | discover | Untitled (9f:3d) | None    | 10.20.0.233 | c8:1f:66:ce:9f:3d |       |                 | True 
#/usr/bin/perl
严格使用;
使用警告;
while(我的$line=){
chomp$行;
my@cells=split/\\\\;/,$line,-1;
my$ncells=标量@单元格;
die“应该有9个字段,但行$.has$ncells”,除非$ncells==9;
对于我的$i(1..$ncells){
如果($cells[$i-1]=~/^\s*$/){
打印“第$行上的单元格#$i为空\n”;
}
}
}
__资料__
id |状态|名称|集群| ip | mac |角色|待定|角色|在线
---|----------|------------------|---------|-------------|-------------------|-------|-----------------|-------
11 | discover | Untitled(9a:3a)| 12 | 10.20.0.144 | c8:1f:66:ce:9a:3a | cinder | True
12 |发现|未命名(9f:8d)| 12 | 10.20.0.186 | c8:1f:66:ce:9f:8d |煤渣,计算|正确
10 | discover | Untitled(c7:f3)| None | 10.20.0.214 | c8:1f:66:ce:c7:f3 | | | True
13 | discover | Untitled(9f:3d)| None | 10.20.0.233 | c8:1f:66:ce:9f:3d | | True
8 | discover | Untitled(74:8e)| 12 | 10.20.0.184 | c8:1f:66:ce:74:8e | controller | True
14 | discover | Untitled(75:4b)| None | 10.20.0.185 | c8:1f:66:ce:75:4b | | True
9 | discover | Untitled(76:23)| None | 10.20.0.213 | c8:1f:66:ce:76:23 | | | True

不要试图将结构化数据视为非结构化行。您有管道分隔的数据,所以将其作为管道分隔的数据进行分析,然后检查所分析内容

请注意,我在单个单元格上使用正则表达式(
/^\s*$/
查看它是否都是空白),但不是在每一行上

下面是一个例子:

13 | discover | Untitled (9f:3d) | None    | 10.20.0.233 | c8:1f:66:ce:9f:3d |       |                 | True 
#/usr/bin/perl
严格使用;
使用警告;
while(我的$line=){
chomp$行;
my@cells=split/\\\\;/,$line,-1;
my$ncells=标量@单元格;
die“应该有9个字段,但行$.has$ncells”,除非$ncells==9;
对于我的$i(1..$ncells){
如果($cells[$i-1]=~/^\s*$/){
打印“第$行上的单元格#$i为空\n”;
}
}
}
__资料__
id |状态|名称|集群| ip | mac |角色|待定|角色|在线
---|----------|------------------|---------|-------------|-------------------|-------|-----------------|-------
11 | discover | Untitled(9a:3a)| 12 | 10.20.0.144 | c8:1f:66:ce:9a:3a | cinder | True
12 |发现|未命名(9f:8d)| 12 | 10.20.0.186 | c8:1f:66:ce:9f:8d |煤渣,计算|正确
10 | discover | Untitled(c7:f3)| None | 10.20.0.214 | c8:1f:66:ce:c7:f3 | | | True
13 | discover | Untitled(9f:3d)| None | 10.20.0.233 | c8:1f:66:ce:9f:3d | | True
8 | discover | Untitled(74:8e)| 12 | 10.20.0.184 | c8:1f:66:ce:74:8e | controller | True
14 | discover | Untitled(75:4b)| None | 10.20.0.185 | c8:1f:66:ce:75:4b | | True
9 | discover | Untitled(76:23)| None | 10.20.0.213 | c8:1f:66:ce:76:23 | | | True

如果必须使用正则表达式,请尽量使其尽可能小。同时假设您的数据中没有|或任何东西

Row id=10 has no pending roles
Row id=13 has no pending roles
Row id=14 has no pending roles
Row id=9 has no pending roles

如果必须使用正则表达式,请尽量使其尽可能小。同时假设您的数据中没有|或任何东西

Row id=10 has no pending roles
Row id=13 has no pending roles
Row id=14 has no pending roles
Row id=9 has no pending roles


当您有分隔符数据时,使用起来就容易多了(或者如果字段可以包含分隔符)。链接到文本文件请不要将您的输入数据放在场外。如果链接断开,此页面的未来访问者将无法看到数据,问题将不再有意义。
\S*
而不是
\S+
使用split或Text::CSV是最常见的选择,但在这种情况下,我可能会使用unpack来提取每个字段。当您有分隔数据时,使用它会更容易(或者如果字段可能包含分隔符).link to text file请不要将您的输入数据放在场外。如果链接断开,此页面的未来访问者将无法看到数据,问题将不再有意义。
\S*
而不是
\S+
使用拆分或text::CSV是最常见的选择,但在这种情况下,我可能使用解包来提取每个字段。取消链接e@Andy Lester的解决方案,如果数据包含
|
,则此解决方案不会失败。最佳选择:使用标头确定字段宽度,这样就不会对字段宽度在一次调用与下一次调用之间的差异敏感(数据可能是来自DB查询的转储)。我喜欢它。这个解决方案还说明了我喜欢的一个引用。。我的解决方案有两个问题与最后一个字段有关。修复。Hi ikegami,解决方案的thx。但是它在线路上失败了----与@Andy Lester的解决方案不同,如果数据包含
|
。非常好的选择:使用标题确定字段宽度hs,这样就不会对字段宽度从一个调用到下一个调用的差异敏感(数据可能是来自DB查询的转储)。我喜欢它。这个解决方案也说明了我喜欢的一句话。。我的解决方案有两个问题与最后一个字段有关。已修复。嗨,ikegami,解决方案是thx。但是它在与--thx alot@Andy Lester的连线上失败了,你的解决方案是迄今为止获取这些单元格最简单和正确的。
split(/\\\/,$line,-1)
并没有
解包('A2)简单多少
my $r = 0; 
foreach my $row (@rows) { 
    my $c = 0; 
    print "Row $r\n"; 
    while($row =~ /([^|])*(\||$)/g) { 
        my $col = $1;
        print "    $c: $col\t"; 
        if ($col =~ /^\s+$/) { print "whitespace only!" }
        print "\n"; 
        $c++;
    }  
    $r++;
}