Regex e o caso dos personagens
Pergunta
Ok, eu tenho um bastante simples (pelo menos parece simples). Eu tenho uma corda multi forrada e estou apenas brincando com a substituição de palavras diferentes por outra coisa. Deixe-me te mostrar...
#!/usr/bin/perl -w
use strict;
$_ = "That is my coat.\nCoats are very expensive.";
s/coat/Hat/igm;
print;
A saída seria
That is my Hat
Hats are very expensive...
O "chapéu" na primeira linha não deve ser capitalizado. Existem truques que podem tornar o revestimento compatível com a escrita em inglês? Obrigado :)
Solução
Vejo Como se replicar e serem-preservar-se-suppercase-Lowercase
Para mais detalhes, vá para Como substituo o caso insensivelmente no LHS enquanto preserva o caso no RHS?
Outras dicas
Você pode usar o e
modificador para s///
Para fazer o truque:
s/(coat)/ucfirst($1) eq $1 ? 'Hat' : 'hat'/igme;
Por um lado, você deve usar \b
(limite da palavra) para combinar apenas a palavra inteira. Por exemplo s/hat/coat/
mudaria That
para Tcoat
sem liderar \b
. Agora para sua pergunta. Com a bandeira /e
Você pode usar o código PERL na parte de substituição do regex. Assim, você pode escrever uma função PERL que verifique o caso da correspondência e, em seguida, defina o caso da substituição corretamente:
my $s = "That is my coat.\nCoats are very expensive.";
$s =~ s/(\bcoat)/&same_case($1, "hat")/igme;
print $s, "\n";
sub same_case {
my ($match, $replacement) = @_;
# if match starts with uppercase character, apply ucfirst to replacement
if($match =~ /^[A-Z]/) {
return ucfirst($replacement);
}
else {
return $replacement;
}
}
Impressões:
That is my hat.
Hats are very expensive.
Isso pode resolver seu problema:
#!/usr/bin/perl -w
use strict;
sub smartSubstitute {
my $target = shift;
my $pattern = shift;
my $replacement = shift;
$pattern = ucfirst $pattern;
$replacement = ucfirst $replacement;
$target =~ s/$pattern/$replacement/gm;
$pattern = lcfirst $pattern;
$replacement = lcfirst $replacement;
$target =~ s/$pattern/$replacement/gm;
return $target;
}
my $x = "That is my coat.\nCoats are very expansive.";
my $y = smartSubstitute($x, "coat", "Hat");
print $y, "\n";