正则表达式仅打印字符串中的重复字母



以下sed代码段将删除字符串中的重复字母并仅打印唯一的字母:

> echo "remove duplicate letters from string" | sed ':;s/(.)(.*)1/12/;t'
> remov duplicatsfng

只打印重复字母的正则表达式是什么 - 因此唯一的字母被丢弃(例如:v和d),并且多次出现的字母不应该在输出中重复!

结果应为:

> remo lits

你可以尝试用GNU sed来做到这一点:

sed -E ':a;s/(.)1*(.+)1+/112/;ta;s/(((.)3)*)./1/g;s/.(.)/1/g;'

详细信息:对于字符串"remove duplicate letters from string"

:a;s/(.)1*(.+)1+/112/;ta; :此部分将每个重复的字母替换为两个连续的字母,这些字母至少由一个字符分隔。结果:

rreemmoov  duplliicattssfng

s/(((.)3)*)./1/g;这个删除了单独存在的字母。结果:

rreemmoo  lliittss

s/.(.)/1/g这个删除了连续的字母。结果:

remo lits

使用 perl:

以或多或少相似的方式,您可以编写如下内容:

perl -pe's/(.)(?!.*1)//g;while(s/(.)(.*)1+/12/g){}'

它更短,但将第二个版本与自动拆分开关和哈希一起使用可能会更有效,以计算每个字符的出现次数:

perl -F -ane'$h{$_}++ for(@F);for(@F){if($h{$_}>1){$h{$_}=1;print}}'

这将适用于任何系统上的任何awk:

$ echo "remove duplicate letters from string" |
awk '{ for (i=1;i<=length($0);) { chr=substr($0,i,1); if (gsub(chr,"") > 1) printf "%c", chr } print "" }'
remo lits

with posix sed(和 gnu)

echo "remove duplicate letters from string" | sed -e ':a' -e 's/((.).*2.*)2/1/;ta' -e "G;:b" -e '/^(.)(.*)1(.*n.*)/s//1231/;tb' -e 's/.//;/^n/b e' -e 'b b' -e ':e' -e 's/.//' 

概念

  • 将字母的出现次数限制为最多两次':a' -e 's/((.).*2.*)2/1/;ta'
  • 使用持有人缓冲区G添加换行符(在末尾)
  • 测试第一个字符是否存在两次(在第二行之前),如果是,请将其放在第二行中并删除字母的第二次出现:b" -e '/^(.)(.*)1(.*n.*)/s//1231/;tb

  • 删除第一个字符s/.//

  • 如果第一个字符是换行符,请转到脚本末尾,删除换行符(并打印)/^n/b e'... -e ':e'
  • 如果不是循环-e 'b b'

这可能对你有用(GNU sed):

sed -r ':a;s/n*(([^n]).*)2/n1/;ta;s/n(.)[^n]*/1/g' file

在删除重复字符时,使用唯一的标记(即n .然后删除所有与标记无关的字符(以及标记),以仅保留那些有重复项的字符。

最新更新