考虑以下完美运行的perl代码:
%replacements = ("what" => "its", "lovely" => "bad");
($val = $sentence) =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/g;
stackoverflow用户sresevoir出色地提出了使用哈希的替换代码,允许您查找和替换多个术语而无需迭代循环。
我已经以编程方式投放其他各种搜索和替换字词,并且我已开始使用它来突出显示搜索结果的字词。
问题(参见下面显示的问题代码):
通过添加" i"使其不区分大小写。在" g"之前在末尾。 如果搜索词$ thisterm和$ sentence中包含的搜索词词在大小写上没有区别,则没有问题。如果搜索项$ thisterm(即Stackoverflow)和$ sentence中包含的搜索项词是不同的情况(即stackoverflow),则返回的结果对于该术语不是任何内容。好像我告诉它
$sentence =~ s/$thisterm//g;
这是问题代码:
foreach $thisterm (@searchtermarray) {
# The variable $thisterm has already gone through a filter to remove special characters.
$thistermtochange = $thisterm;
$replacements{$thistermtochange} = "<span style=\"background-color:#FFFFCC;\">$thistermtochange<\/span>";
}
$sentence =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/ig;
我还回过头来用上面的原始代码重复了这个问题。似乎添加i修饰符,使用哈希引用和不同情况的组合是Perl不喜欢的。
我错过了什么?
谢谢,
DB
P上。 S.我多年来从stackoverflow中受益;但我刚刚注册了这个问题,该网站不会让我直接评论sresevoir。作为一个全新的&#34;用户我没有足够的声誉点。
答案 0 :(得分:1)
将散列的所有键保持为小写,并执行以下操作:
s/(@{[join "|", keys %replacements]})/$replacements{ lc $1 }/ig
(注意增加lc)
还有一些其他事情你应该考虑。
首先,如果您尝试使用不同的替换替换lovely
和love
,则可能会找到lovely
,也可能找不到keys
,具体取决于返回的是哪个键s/(@{[join "|", sort { length $b <=> length $a } keys %replacements]})/$replacements{$1}/ig
首先。为了防止这种情况,按降序排序是个好主意:
how?
其次,这种技术仅适用于固定字符串;如果您的密钥包含任何正则表达式元字符,例如将why?
替换为$1
,则会失败,因为how?
永远不会是s/(@{[join "|", map quotemeta, sort { length $b <=> length $a } keys %replacements]})/$replacements{$1}/ig
。要允许元字符(解释为文字字符),请引用它们:
s/(@{[join "|", map quotemeta, sort { length $b <=> length $a } @search_strings]})/<span style="background-color:#FFFFCC;">$1<\/span>/ig;
从你的评论中,我觉得你想要在一次通过中找到某些字符串,并在它们周围添加东西(不会因字符串而异)。如果是这样,那么你就是在艰难的道路上进行,并且根本不应该使用哈希。有一个你想要搜索的字符串数组并替换它们:
{{1}}
答案 1 :(得分:0)
问题是,如果你有像这样的哈希
my %replacements = (
word => '<span style="background-color:#FFFFCC;">word</span>'
)
然后替换将看起来像
s/(word)/$replacements{$1}/ig;
但是,与案例无关的正则表达式模式也会与WORD
匹配,因此替换表达式$replacements{$1}
将为$replacements{'WORD'}
,但不存在。
虽然您可能对他的解决方案感到满意,但sresevoir
使用了一种在正则表达式中嵌入字符串表达式的丑陋方式。此
($val = $sentence) =~ s/(@{[join "|", keys %replacements]})/$replacements{$1}/g;
会好得多。
my $pattern = join '|', keys %replacements;
($val = $sentence) =~ s/($pattern)/$replacements{$1}/g;
但是你已经把这个哈希想法推广得太过分了,而且你做出你需要的改变是错误的。如果替换字符串是原始字符串的简单函数(如本例所示),则最好使用模式中的捕获将其直接写为替换字符串。我会这样写的
my $pattern = join '|', @searchtermarray;
$sentence =~ s{($pattern)}{<span style="background-color:#FFFFCC;">$1</span>\n}ig;
但请注意,就目前情况而言,搜索会在文本中找到任何子串的字词,如果@searchtermarray
包含任何字符串,也会出错正则表达式元字符。你没有说出你的实际数据,所以我无法真正帮助你解决这个问题。