如何将字母o
与e
和e
与o
交换?
我刚试过这个,但我不认为这是一个很好的方法。还有更好的方法吗?
my $str = 'Absolute force';
$str =~ s/e/___eee___/g;
$str =~ s/o/e/g;
$str =~ s/___eee___/o/g;
输出:Abseluto ferco
答案 0 :(得分:25)
$str =~ y/oe/eo/;
E.g。
$ echo "Absolute force" | perl -pe 'y/oe/eo/'
Abseluto ferco
答案 1 :(得分:8)
正如已经说过的,这样做的方法是transliteration operator
tr/SEARCHLIST/REPLACEMENTLIST/cdsr
y/SEARCHLIST/REPLACEMENTLIST/cdsr
使用替换列表中的相应字符音译搜索列表中找到的所有出现的字符。它返回替换或删除的字符数。如果未通过
=~
或!~
运算符指定字符串,则$_
字符串将被音译。
但是,我想赞扬您对正则表达式的创造性使用。您的解决方案有效,但占位符字符串_ee_
已足够。
tr
只会帮助你进行角色替换,所以我想快速教你如何利用正则表达式进行更复杂的质量替换。基本上,您只需使用/e
标记在RHS中执行代码。以下内容也将用于您的目标:
my $str = 'Absolute force';
$str =~ s/([eo])/$1 eq 'e' ? 'o' : 'e'/eg;
print $str;
输出:
Abseluto ferco
注意LHS(左侧)如何匹配o
和e
,并且RHS(右侧)进行测试以查看哪个匹配并返回相反的替换。< / p>
现在,通常会有一个要替换的单词列表,因此可以方便地构建from / to值的哈希值,然后动态构建正则表达式。以下是:
my $str = 'Hello, foo. How about baz? Never forget bar.';
my %words = (
foo => 'bar',
bar => 'baz',
baz => 'foo',
);
my $wordlist_re = '(?:' . join('|', map quotemeta, keys %words) . ')';
$str =~ s/\b($wordlist_re)\b/$words{$1}/eg;
输出:
Hello, bar. How about foo? Never forget baz.
上述内容可能适用于您的e
和o
案例,但这样做会有些过分。请注意我如何使用quotemeta
来转义键,以防它们包含正则表达式特殊字符。我还故意在$wordlist_re
中使用了一个非捕获组,以便变量可以放入任何正则表达式并按照需要运行。然后我将捕获组放在s///
内,因为能够看到正则表达式中捕获的内容非常重要,而不必回溯到插值变量的值。
答案 2 :(得分:2)
来自man sed
:
<强> Y /源/目标/ 强> 将源中出现的模式空间中的字符音译为dest中的相应字符。
和tr
命令也可以这样做:
$ echo "Absolute force" | tr 'oe' 'eo'
Abseluto ferco
答案 3 :(得分:2)
tr///
运营商是最好的。但是,如果您想使用s///
运算符(处理多个单字母替换),您可以编写
$ echo 'Absolute force' | perl -pe 's/(e)|o/$1 ? "o" : "e"/eg'
Abseluto ferco
捕获括号可以避免在@ Miller的答案中进行多余的$1 eq 'e'
测试。