Regex perl不匹配字符串搜索
如何发现一个字符串中是否存在一个或两个不匹配的字符串Regex perl不匹配字符串搜索,regex,perl,mismatch,Regex,Perl,Mismatch,如何发现一个字符串中是否存在一个或两个不匹配的字符串 my $find = "MATCH"; my $search = "stringisMATTHhere"; # $search has one mismatch: MATTH # for exact match, this one seems working if ($search =~ /$find/){ print "String found"; } else { print "String n
my $find = "MATCH";
my $search = "stringisMATTHhere";
# $search has one mismatch: MATTH
# for exact match, this one seems working
if ($search =~ /$find/){
print "String found";
}
else {
print "String not found";
}
我如何解决一个不匹配的问题:MSTCH、AATCH、MACCH等,以及两个不匹配:ATTCH、MGGCH等。据我所知,只有一个使用特殊正则表达式引擎的方便解决方案: 下面是您示例的解决方案:
#!/usr/bin/perl
use strict;
use warnings;
use re::engine::TRE max_cost => 2;
my $find = "MATCH";
my $search = "stringisMATTHhere";
if ($search =~ /\($find\)/) {
print $1,"\n";
}
这将产生:
$ perl fuzzy_re.pl
MATTH
据我所知,只有一种使用特殊正则表达式引擎的方便解决方案: 下面是您示例的解决方案:
#!/usr/bin/perl
use strict;
use warnings;
use re::engine::TRE max_cost => 2;
my $find = "MATCH";
my $search = "stringisMATTHhere";
if ($search =~ /\($find\)/) {
print $1,"\n";
}
这将产生:
$ perl fuzzy_re.pl
MATTH
我对这个很感兴趣,所以我想我应该多尝试一些
以可控的方式改变 功能:
-可以为单个查找设置最小/最大不匹配范围。
-可以设置一个标志,以在不匹配计数中排除/包括0x20或更少的空间。
-自动转义find中的元字符 就这样。
祝你好运
正则表达式:
(?s)
(?{ $cnt = 0; $lcnt = 0 })
(?:
(?>
(??{ $aryinput[$lcnt++] })
| (?&getexpr)
)
){$len}
(??{ $cnt >= $mincnt && $cnt <= $maxcnt ? '' : '(?!)' })
(?(DEFINE)
(?<getexpr>
(??{ ++$cnt <= $maxcnt ?
( $visible_only ?
( $aryinput[$lcnt-1] le ' ' ?
'(?!)'
: '[^\x{0}-\x{20}]'
)
: '.'
)
: '(?!)'
})
)
)
我对这个很感兴趣,所以我想我应该多尝试一些
以可控的方式改变 功能:
-可以为单个查找设置最小/最大不匹配范围。
-可以设置一个标志,以在不匹配计数中排除/包括0x20或更少的空间。
-自动转义find中的元字符 就这样。
祝你好运
正则表达式:
(?s)
(?{ $cnt = 0; $lcnt = 0 })
(?:
(?>
(??{ $aryinput[$lcnt++] })
| (?&getexpr)
)
){$len}
(??{ $cnt >= $mincnt && $cnt <= $maxcnt ? '' : '(?!)' })
(?(DEFINE)
(?<getexpr>
(??{ ++$cnt <= $maxcnt ?
( $visible_only ?
( $aryinput[$lcnt-1] le ' ' ?
'(?!)'
: '[^\x{0}-\x{20}]'
)
: '.'
)
: '(?!)'
})
)
)
那么你想做什么
/
..TCH | .A.CH | .AT.H | .ATC. |
M..CH | M.T.H | M.TC. |
MA..H | MA.C. |
MAT..
/x
或
很简单:
my @subpats;
for my $i (0..length($find)-1) {
for my $j ($i+1..length($find)-1) {
my $subpat = join('',
substr($find, 0, $i),
'.', # or '\\w'
substr($find, $i+1, $j-$i-1),
'.', # or '\\w'
substr($find, $j+1),
);
push @subpats, $subpat;
}
}
my $pat = join('|', @subpats);
$search =~ /$pat/
基于perl5.10+trie的替换应该将公共前导前缀优化为高效的前缀。为我们省去了生成(?:..| M…)
的麻烦,所以您想这样做
/
..TCH | .A.CH | .AT.H | .ATC. |
M..CH | M.T.H | M.TC. |
MA..H | MA.C. |
MAT..
/x
或
很简单:
my @subpats;
for my $i (0..length($find)-1) {
for my $j ($i+1..length($find)-1) {
my $subpat = join('',
substr($find, 0, $i),
'.', # or '\\w'
substr($find, $i+1, $j-$i-1),
'.', # or '\\w'
substr($find, $j+1),
);
push @subpats, $subpat;
}
}
my $pat = join('|', @subpats);
$search =~ /$pat/
基于perl5.10+trie的替换应该将公共前导前缀优化为高效的前缀。为我们省去了生成
(?:..| M…)
的麻烦。如果搜索的字符串应具有与后面注释中所述相同的长度(即仅允许不匹配),则可以使用汉明距离,该距离非常快:
#!/usr/bin/perl
use strict;
use warnings;
my $find = "MATCH";
my $search = "stringisMATTHhere";
my $max_distance = 2;
for my $offset (0..length($search)-length($find)) {
my $hd = hd($find,substr($search,$offset,length($find)));
if ($hd <= $max_distance) {
print substr($search,$offset,length($find)),"\n";
}
}
# assumes byte mode
sub hd {
return ($_[0] ^ $_[1]) =~ tr/\001-\255//;
}
#/usr/bin/perl
严格使用;
使用警告;
我的$find=“MATCH”;
my$search=“stringisMATTHhere”;
我的$max_距离=2;
对于我的$offset(0..length($search)-length($find)){
my$hd=hd($find,substr($search,$offset,length($find));
如果($hd如果搜索字符串的长度应与后面的注释中所述的长度相同(即仅允许不匹配),则可以使用汉明距离,这非常快:
#!/usr/bin/perl
use strict;
use warnings;
my $find = "MATCH";
my $search = "stringisMATTHhere";
my $max_distance = 2;
for my $offset (0..length($search)-length($find)) {
my $hd = hd($find,substr($search,$offset,length($find)));
if ($hd <= $max_distance) {
print substr($search,$offset,length($find)),"\n";
}
}
# assumes byte mode
sub hd {
return ($_[0] ^ $_[1]) =~ tr/\001-\255//;
}
!/usr/bin/perl
严格使用;
使用警告;
我的$find=“MATCH”;
my$search=“stringisMATTHhere”;
我的$max_距离=2;
对于我的$offset(0..length($search)-length($find)){
my$hd=hd($find,substr($search,$offset,length($find));
如果此任务需要编辑距离而不是正则表达式,则此问题作为的副本关闭,但该问题不涉及搜索更大的字符串。不匹配是否只是更改了字符,而不是添加/删除/交换了字符?实际查找的字符串有多长?搜索字符串(大约20个字符)如果在另一个字符串(1000个字符)中存在,则检查部分字符串(如果存在)-在20个字符的字符串位置的任意位置仅一个或两个位置(无删除、添加、精确的20个字符)此任务需要编辑距离而不是正则表达式此问题作为的副本关闭,但该问题不涉及搜索更大的字符串。不匹配是否只是更改了字符,而不是添加/删除/交换了字符?您实际查找的字符串有多长?搜索字符串(大约20个字符)如果在另一个字符串(1000个字符)中存在,则检查部分字符串(如果存在)-在20个字符的字符串位置的任意位置仅一个或两个位置(无删除、添加、精确的20个字符)使用点
而不是\w
会更一般,这取决于需求。可能希望将/s
与
一起使用,但这又取决于需求。@ikegami:这对两个不匹配非常有效。如何仅对一个不匹配修改代码。我无法修改。感谢使用点>.
而不是\w
会更一般,具体取决于需求。可能希望将/s
与
一起使用,但同样取决于需求。@ikegami:这对两个不匹配非常有效。如何仅对一个不匹配的代码进行修改。我无法修改。非常感谢。MTCH
会匹配,但OP在评论中提到只允许替换,不允许插入或删除。我认为您的解决方案可以通过使用use re::engine::TRE max_cost=>2,max_ins=>0,max_del=>0;
而不是使用re::engine::TRE max_cost=>2;
@ikegami我试过use re::engine::最大成本=>2,最大插入=>0,最大删除=>0;
但MTCH
匹配too@SSh似乎是个bug。这是有效的:use re::engine::TRE max_cost=>2,cost_ins=>-1,cost_del=>-1;
不完全匹配。MTCH
会匹配,但注释中提到的OP只允许替换,不允许插入或删除。我很瘦k您的解决方案可以通过使用use re::engine::TRE max_cost=>2,max_ins=>0,max_del=>0;
替代或使用re::engine::TRE max_cost=>2;
我尝试过的@ikegami使用re::engine::TRE max_cost=>2,max_ins=>0,max_del=>0;
但MTCH
匹配too@SSh看起来像个虫子。这个工作原理:use re::engine::TRE max\u cost=>2,cost\u ins=>-1,cost\u del=>-1;