如何删除 : 分隔列表中的重复字符或字符串?

ath*_*mas 3 scripting text-processing

例如,在a:bc:d:a:hi:p:a删除重复项a和在apple:orange:apple:.:pear:mango:.:apple- 删除重复项apple

Rom*_*est 5

GNU awk解决方案(将保留所有分隔符):

s="apple:orange:apple:.:pear:mango:.:apple"
awk '{ len=split($0,a,/:|:\.:/,seps); 
       for(i=1;i<=len;i++) printf "%s%s",(!w[a[i]]++? a[i]:""),(i==len? "":seps[i]);
       print "" }' <<<"$s"
Run Code Online (Sandbox Code Playgroud)
  • len=split($0,a,/:|:\.:/,seps)- 将字符串分成由正则表达式模式分隔/:|:\.:/的部分,并将这些部分存储在数组中a,并将分隔符字符串存储在seps数组中。

  • len - 包含由于拆分而​​创建的元素/块的数量


输出:

apple:orange::.:pear:mango:.:
Run Code Online (Sandbox Code Playgroud)


Ser*_*nyy 5

有序的 Python 解决方案

如果顺序很重要,以下是我们可以在 python 中作为单行执行的操作:

$ python -c 'import sys;from collections import OrderedDict; d=OrderedDict( (i,True) for i in sys.argv[1].split(":") );print ":".join(d.keys())'  'apple:orange:apple:.:pear:mango:.:apple'
apple:orange:.:pear:mango
Run Code Online (Sandbox Code Playgroud)

有点长,所以我们可以把它变成一个小脚本:

$ python -c 'import sys;from collections import OrderedDict; d=OrderedDict( (i,True) for i in sys.argv[1].split(":") );print ":".join(d.keys())'  'apple:orange:apple:.:pear:mango:.:apple'
apple:orange:.:pear:mango
Run Code Online (Sandbox Code Playgroud)

并使用它:

$ ./uniq_tokens.py 'apple:orange:apple:.:pear:mango:.:apple'                                                                                                           
apple:orange:.:pear:mango
Run Code Online (Sandbox Code Playgroud)

这是工作的方式:

  • 我们将希望处理的字符串作为命令行参数给出,因此我们使用sysmodule 来引用sys.argv[1]
  • sys.argv[1]使用:作为分隔符将 get 拆分为令牌
  • (i,True) for i in sys.argv[1].split(":")允许我们创建具有两个值的元组列表,其中True只是虚拟值
  • OrderedDict然后获取这些并创建一个键值对字典。这是一种“便宜”的方法,可以使用列表理解来制作有序集作为字典理解的替代方法。如果字符串已经作为键存在,它将保持唯一(除非你做了一些不必要的事情
  • ":".join()将允许我们获取我们拆分的所有标记(因此我们d.keys()在这里使用),然后转换回一个漂亮的整个字符串:
  • 打印是不言自明的。

无序(但更短)的 Python 解决方案

如果顺序无关紧要,我们可以得到一个更短的解决方案(但这更多是为了好玩而不是实际应用 - 可能 99% 的时间您想要保留令牌的顺序):

$ python -c  'import sys;print ":".join(set(sys.argv[1].split(":")))'  'a:bc:d:a:hi:p:a'                                                                               
a:p:hi:d:bc
Run Code Online (Sandbox Code Playgroud)

其工作方式很简单:

  • 我们将所需的字符串作为命令行参数传递,因此我们需要import sys将第一个命令行参数称为sys.argv[1]
  • 现在,让我们打开第二部分;sys.argv[1].split(":") 从最初的整个字符串中给了我们一个令牌列表,我们使用:作为单个令牌的分隔符进行拆分
  • set() 将采用上面提到的字符串列表并为我们提供唯一值
  • 现在,我们需要将这个字符串集合转换回一个完整的字符串,这就是为什么我们使用作为分隔符":".join()再次将所有标记拼接在一起的原因:
  • print是不言自明的。请注意,这是 Python 2.7 语法。使用print()的Python 3

这是对其他字符串的测试:

$ python -c  'import sys;print ":".join(set(sys.argv[1].split(":")))'  'apple:orange:apple:.:pear:mango:.:apple'                                                       
orange:mango:pear:apple:.
Run Code Online (Sandbox Code Playgroud)