perl - 如何在两条路径 Perl 之间查明不匹配的段/解析
问题描述
我有 2 条路径需要比较,如果不匹配,我想指出哪个子路径或路径不匹配。有没有更好的方法来做到这一点?这仅适用于 2 条路径,我有很多需要比较的路径。
#!/usr/bin/perl
use warnings;
use strict;
my $realPath= 'C/library/media/music/retro/perl.mp3'; #Absolute
my $comparedPath= 'music/classic/perl.mp3'; #Relative, a sample that need to be compare with the $realPath
my @compared_array;
my @realpath_array;
my %compared_hash;
tie %compared_hash, 'Tie::IxHash';
my %realpath_hash;
tie %realpath_hash, 'Tie::IxHash';
if ( $realPath=~ m/$comparedPath$/)
{
print "$comparedPath exist";
}
else
{
print "$comparedPath is not exist";
@compared_array=split /\//,$comparedPath;
@realpath_array=split /\//,$realPath;
}
@compared_hash{@compared_array}=1;
@realpath_hash{@realpath_array}=1;
foreach my $key (keys %compared_hash)
{
delete $compared_hash{$key} if (grep {$_ =~/$key/} (keys %realpath_hash));
#leaving only unmatch Path Segment/Parse
}
print join("\n",%compared_hash);
输出:
classic
解决方案
他们可以通过多种方式进行比较。
- 它们根本不重叠。
- 它们重叠,但一个太短了。
- 它们部分重叠。
- 它们完美重叠。
使用File::Spec->splitpath 和 splitdir将路径转换为数组。那么问题就变成了比较数组的问题。它在它自己的函数内部也简单得多,因为我们return
一得出结论就可以。
首先,我们可以使用List::MoreUtils::after_incl找到它们开始重叠的点。在您的示例@remainder
中是qw(music retro perl.mp3)
.
my @remainder = after_incl { $_ eq $rel_path->[0] } @$abs_path;
if( !@remainder ) {
say "The paths do not overlap";
return;
}
然后我们可以@remainder
和路径一起走,找到它们分歧的地方。我们还需要确保我们不会偏离正轨。
for my $idx (1..$#remainder) {
if( $idx > $#$rel_path ) {
say "The path is too short";
return;
}
if( $remainder[$idx] ne $rel_path->[$idx] ) {
say "The paths differ at $remainder[$idx] vs $rel_path->[$idx]";
return;
}
}
最后,如果它们匹配,我们需要检查路径的尽头是否还有更多。
if( @$rel_path > @remainder ) {
say "The path is too long";
return;
}
如果它通过了所有这些,它们就会重叠。
say "The path is a child";
return;
把它们放在一起...
use strict;
use warnings;
use v5.10;
use List::MoreUtils qw(after_incl);
sub find_difference {
my($abs_path, $rel_path) = @_;
my @remainder = after_incl { $_ eq $rel_path->[0] } @$abs_path;
if( !@remainder ) {
say "The paths do not overlap";
return;
}
for my $idx (1..$#remainder) {
if( $remainder[$idx] ne $rel_path->[$idx] ) {
say "The paths differ at $remainder[$idx] vs $rel_path->[$idx]";
return;
}
}
if( @$rel_path > @remainder ) {
say "The path is too long";
return;
}
say "The path is a child";
return;
}
find_difference(
[qw(library media music retro perl.mp3)],
[qw(music retro perl.mp3 foo bar)]
);
推荐阅读
- javascript - 意外的标记 ';' 在尝试使用 if else 来决定 DOM 操作时在随机生成器中
- spring - springMVC中没有映射错误如何解决?
- c# - 从 Windows Server 2008 移动到 2016 后收到 MSMQ 错误
- node.js - 如何在 Vue 中使用 Express
- powershell - 只需遍历 XML 文件,列出节点供用户选择
- javascript - 在另一个数组中过滤数组
- r - 如何在 R 中使用“唯一”和“排序”
- python - 如何在 Python 中可视化隔离森林算法?
- reactjs - 无法通过 react-router 使用 props.history.push 进行重定向
- laravel - SQLSTATE [42S22]:未找到列:1054 未知列