正则表达式只能打印字符串

时间:2017-01-10 21:48:37

标签: regex sed

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

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

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

结果应为:

> remo lits

4 个答案:

答案 0 :(得分:4)

您可以尝试使用GNU sed:

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

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

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

rreemmoov  duplliicattssfng

s/(((.)\3)*)./\1/g;这个删除了一个人留下的字母。结果:

rreemmoo  lliittss

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

remo lits

使用perl:

你可以用或多或少类似的方式写下这样的东西:

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

它更短但是使用第二个版本和autosplit开关并使用哈希来计算每个字符的出现次数可能更有效:

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

答案 1 :(得分:1)

这适用于任何系统上的任何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

答案 2 :(得分:1)

使用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//\1\2\3\1/;tb' -e 's/.//;/^\n/b e' -e 'b b' -e ':e' -e 's/.//' 

概念

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

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

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

答案 3 :(得分:0)

这可能适合你(GNU sed):

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

虽然删除重复字符前缀,但使用唯一标记\n。然后删除与标记无关的所有字符(以及标记),只留下那些具有重复字符的字符。