我可以写一个sed
匹配模式的模式吗氨基酸,BB,抄送等等(即,给定一个大写字母,它应该与相应的小写字母匹配)而不枚举所有可能性?
答案1
使用perl
,您可以执行以下操作:
$ echo 'fooÉébAar' | perl -Mopen=locale -pe 's/([[:upper:]])(??{lc$^N})/<$&>/g'
foo<Éé>b<Aa>r
它使用(??{code})
特殊的 perl 运算符,您可以在其中动态指定要匹配的正则表达式。这是最后一个捕获组lc$^N
的小写版本。$^N
使用 GNU sed
,你可以这样做:
$ echo 'fooÉébAar' | sed -Ee 's/./&\L&/g;s/([[:upper:]](.)\2.)/<<\1>>/g;s/(.)./\1/g'
foo<Éé>b<Aa>r
这个想法是,我们首先在输入中附加每个字符的小写版本(X
becomes Xx
,x
becomes xx
),所以如果我们看到Xxx
后面有一个(([[:upper:]](.)\2
:X
后面跟着一个重复的字符),这意味着我们有一个大写字符,后面跟着它的小写版本。
请注意,这些不适用于分解形式的字符。例如,É
当表达为E
后跟结合尖锐的口音。要解决这个问题,您可以使用perl
的\X
graphem cluster regexp 运算符代替:
$ printf 'E\u0301\u0302\u00e9\u0302 \u00c9e\u301 foo Ee\u301\n' |
perl -Mopen=locale -MUnicode::Normalize -pe '
s/((?=[[:upper:]])\X)(?{$c1 = $^N})(\X)(??{
NFD(lc$c1) eq NFD($^N) ? qr{} : qr{(?!)}})/<$&>/g'
<É̂é̂> <Éé> foo Eé
以上使用规范规范化形式( NFD
) 使得字素簇在字符级别总是以相同的方式表示。
它仍然无法匹配诸如(U+FB03) 是单个(印刷连字)字符的Fffi
情况ffi
,但无论如何这可能也是如此。
答案2
如果您正在使用塞德结合重击或者兹什,你可以只使用一个小的元程序, 像那样:
代码
>echo "AaBCAABbEE"| sed -E "s/`echo {A..Z}|sed -E 's/\w/&\L&/g;y/ /|/'`/%/g"
%BCAA%EE
这将有效地为您生成所有组合,使用外壳大括号扩展(和嵌套sed),如下图所示:
>echo {A..Z}|sed -E 's/\w/&\L&/g;y/ /|/'
Aa|Bb|Cc|Dd|Ee|Ff|Gg|Hh|Ii|Jj|Kk|Ll|Mm|Nn|Oo|Pp|Qq|Rr|Ss|Tt|Uu|Vv|Ww|Xx|Yy|Zz
可能也有一些纯 Sed 方法可以做到这一点,例如,通过连续应用多个替换和/或使用保留空间来逐一搜索这些对。
答案3
结合 bash 和 sed(在本例中我使用 sed 来匹配和删除字母):
$ word="Hey , This is AaBbCc and also Dd!"
$ search="H";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
ey , Tis is AaBbCc and also Dd!
$ search="A";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
Hey , This is BbCc nd lso Dd!
$ search="D";search2=${search,,};sed "s/[$search$search2]//g" <<<"$word"
Hey , This is AaBbCc an also !
您只需在 var“search=”处提供大写的搜索字母即可。
PS:如果你需要搜索小写字母,那么可以将它们转换为大写字母${search^^}