我想匹配两个仅在元素和换行符方面不同的字符串
$string1 = "perl is <match>scripting language</match>";
$string2 = "perl<TAG> is<TAG> scr<TAG>ipt<TAG>inglanguage";
注意:spaces
和<TAG>
以及newline
可以出现在string2中的任何位置。例如,字符串2中可能存在或不存在空格,例如在上面的实例中,缺少单词脚本语言之间的$ string2空格。在将string1与string2匹配时,我们必须忽略空格,标签,换行符。 string1中的<match>
标记表示要与string2匹配的数据
需要输出:
string2的整个内容以及<match>
标记
perl <TAG>
为<TAG>
<match>
scr <TAG>
ipt <TAG>
inglanguage </match>
我试过的代码:
while($string =~ /<match>(.*?)<\/match>/gs)
{
my $data_to_match = $1;
$data_to_match = add_pat($data_to_match);
$string2 =~ s{($data_to_match)}
{
"<match>$&<\/match>"
}esi;
}
sub add_pat
{
my ($data) = (@_);
my @array = split//,$data;
foreach my $each(@array)
{
$each = quotemeta $each;
$each = '(?:(<TAG>|\s)+)?'.$each.'(?:(<TAG>|\s)+)?';
}
$data = join '',@array;
return $data;
}
问题:因为string2中缺少空格所以它不匹配。我尝试在为每个字符添加模式时使空间可选。但要使空间可选。 $ string模式继续运行。
实际上,我有大字符串要匹配。这些空间引起了问题。请建议
答案 0 :(得分:1)
使用正则表达式从两个字符串中删除您要忽略的所有字符。然后比较两个字符串的剩余值。
所以你最终会得到两个字符串,例如:
'perlisscriptinglanguage' and 'perlisscriptinglanguage'
如果你想要你也可以大写/小写它们也匹配。
如果匹配则返回原始字符串2.
答案 1 :(得分:0)
我认为你应该“匹配”这很奇怪。但$ string2,如果取出标签,则与原始字符串不匹配。
无论如何,由于你的代码可以容忍$ string2中的额外空格和标签,那么你可以从$ string1中擦除所有空格(和标签,如果适用)。
我在调用add_pat之前添加了$data_to_match =~ s/ +//;
。这没有用,因为这行“$ each ='(?:( | \ s)+)?'。$ each。'(?:( | \ s)+)?';”添加(?:( | \ s)+)?'甚至在你的$ string1的第一封比赛信之前。实际上你有很多冗余的TAG模式,你可以在每个字母的正面和背面添加一个。我不知道quotemeta做了什么,所以我不知道如何修复那里的代码。我刚添加了
调用add_pat之后$data_to_match =~ s/\Q(?:(<TAG>|\s)+)?\E//;
行从模式的前面去掉第一个TAG模式。否则它会匹配错误并输出'perl&lt; TAG&GT;为&lt;匹配&GT;&LT; TAG&GT; SCR&LT; TAG&GT; IPT&LT; TAG&GT; inglanguage&LT; /匹配&GT;'
真的,你应该只放一个“(?:( | \ s)+)?”在$ string1匹配的每个字母之间,更重要的是;你不应该把“(?:( | \ s)+)?”在第一个字母之前或在最后一个字母之后。