正则表达式和字符的情况下

问题描述:

好吧,我有一个相当简单的(至少看起来很简单)。我有一个多行字符串,我只是在用其他的东西替换不同的单词。让我告诉你......正则表达式和字符的情况下

#!/usr/bin/perl -w 
use strict; 

$_ = "That is my coat.\nCoats are very expensive."; 
s/coat/Hat/igm; 
print; 

输出将
That is my Hat
Hats are very expensive...

在第一行的“帽子”不应该大写。是否有任何技巧可以使外壳符合英语的写法?谢谢:)

+0

我想你是不是在油漆和涂料行业的工作? :) – 2010-08-12 07:49:23

+0

首先,不要使用修饰符我,如果你想区分大小写。 – 2010-08-12 07:55:28

+0

您需要定义您的范围。你打算在*很多词上使用这个词吗? – Zaid 2010-08-12 07:59:18

+0

我不知道这已经是问:| – David 2010-08-14 09:13:20

+0

@Davidmoreen:没关系:-) – 2010-08-14 09:41:05

首先,你应该使用\b(字边界)只匹配整个单词。例如,s/hat/coat/会将That更改为Tcoat而不会导致\b。现在为你的问题。通过标记/e,您可以在正则表达式的替换部分中使用Perl代码。所以,你可以写一个Perl函数,用来检查本场比赛的情况下,然后设置替换的情况下正常:

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; 
     } 
} 

打印:

That is my hat. 
Hats are very expensive. 

可以使用e修饰符s///做诀窍:

s/(coat)/ucfirst($1) eq $1 ? 'Hat' : 'hat'/igme; 
+1

不是一个完整的解决方案,但它涵盖'大衣'和'帽子' – Axeman 2010-08-12 13:05:23

+0

聪明的解决方案! – David 2010-08-14 09:12:50

这可能会解决你的问题:


#!/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";