当字符串 A 中出现中文字符时,如何从字符串 B 中删除它们,同时保留顺序?

当字符串 A 中出现中文字符时,如何从字符串 B 中删除它们,同时保留顺序?

我有一些很长的汉字字符串,但为了这个问题,我们假设它们是:

啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板

阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔

第一个字符串列出了所有“简单”的汉字。第二个字符串列出了所有“易”和“中”汉字,但我只想要“中”汉字:我想从第二个字符串中删除“易”字符。

例如,编辑后,第二个字符串将不包含“啊”或“爱”(可能还有更多删除),因为它们都出现在第一个字符串中。

问题: 当字符串A中出现中文字符时,如何从字符串B中删除它们,同时保留顺序?

我觉得这应该可以用awkor解决sed或者其他东西来解决;我不介意。看起来我可以将这些字符串转换为两个文本文件,并使用中的任何一个命令如何从另一个文件A中删除文件B上出现的行? 但是,我宁愿在不创建辅助文件的情况下执行此操作。

保留字符串中字符的顺序也很重要。

答案1

在允许语法${parameter/pattern/string}(ksh、bash、zsh)的 shell 中,您可以执行以下操作:

$ easy='啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板'
$ intermediate='阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔'

$ echo "${intermediate//[$easy]/}" 
阿姨挨打矮小国护检慰置岸边上摩时案子暗示巴士拔

这是基于类似正则表达式的字符选择[…]。其中也存在的
所有单个字符都将被删除。intermediateeasy

独立于 shell 的等效项可能是:

$ echo "$intermediate" | sed 's/['"$easy"']//g'

阿姨挨打矮小国护检慰置岸边上摩时案子暗示巴士拔

答案2

使用 Raku(née Perl6)

Raku 的设计初衷就是为了优雅地处理 Unicode。下面每对的第一个示例通常来自 Raku 文档;每对的第二个例子适用于解决您的特定中文字符串:

$ echo "a123b123c" | raku -pe 'tr:d/123//;'
abc
$ echo "阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔" | raku -pe 'tr:d/啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板//;'
阿姨挨打矮小国护检慰置岸边上摩时案子暗示巴士拔

或者

$ echo "a123b123c" | raku -pe '.=trans("123" => "");'
abc
$ echo "阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔" | raku -pe '.=trans("啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板" => "");'
阿姨挨打矮小国护检慰置岸边上摩时案子暗示巴士拔

命令-pe行标志指示 Raku 按行获取输入并自动打印返回值。tr///操作员和例程之间存在细微差别trans()。下面的文档,HTH。

https://docs.raku.org/language/operators#tr///_in-place_transliteration
https://docs.raku.org/routine/trans
https://raku.org/

答案3

我想到了!它可能不是最好的解决方案,但它有效:

echo 阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔 | sed -e "s/.\{1\}/&\n/g" | awk -v pat="啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板" 'pat ~ $0' | tr -d '\n'

解释:

  • echo 阿姨啊挨打矮小爱国护安检慰置岸边上按摩时案子暗示巴士拔是一种将第二个字符串作为输入进行管道传输的方法
  • sed -e "s/.\{1\}/&\n/g"在每个字符后添加换行符
  • awk -v pat="啊爱好情人心安静排全装按照八把握爸吧白菜酒色夭百班长板" 'pat !~ $0'pat仅打印(第一个字符串)中未出现的字符
  • tr -d '\n'摆脱所有换行符

它给出了输出

阿姨挨打矮小国护检慰置岸边上摩时案子暗示巴士拔

并删除字符“啊”、“爱”、“安”、“按”。

相关内容