首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >正则表达式以匹配文件中的唯一单词

正则表达式以匹配文件中的唯一单词
EN

Stack Overflow用户
提问于 2009-11-03 08:15:05
回答 4查看 2.8K关注 0票数 3

要在文件中以" unique :“作为唯一单词的前缀,我尝试使用perl regex命令,如下所示:

代码语言:javascript
复制
perl -e 'undef $/;while($_=<>){s/^(((?!\b\3\b).)*)\b(\w+)\b(((?!\b\3\b).)*)$/\1UNIQUE:\3\4/gs;print $_;}' demo

在演示文件中,其中包括:

代码语言:javascript
复制
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon

产出如下:

代码语言:javascript
复制
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
UNIQUE:lemon

不幸的是,如果提前使用,\3反向引用似乎不会被处理。

是否有其他方法可以通过另一个regex或Linux盒上可用的其他常用命令来实现这一目的?(grep,sed,awk,.)

非常感谢

编辑:不幸的是,许多解决方案只适用于所提供的不完整的情况,我对此表示歉意,它还应该处理以下文本:

代码语言:javascript
复制
{watermelon || banana}
apple = ( pear pineapple orange mango )
strawberry cherry
kiwi = pineapple = lemon = cranberry = watermelon
orange - plum = cherry
kiwi = banana + plum
mango = cranberry && apple
lemon

如果它简化了问题,单词的前缀可能是$或@。

EN

回答 4

Stack Overflow用户

发布于 2009-11-03 09:00:41

不可能只执行regexp一次就可以做到这一点。这是因为在完成第一个替换之后,内部游标会在匹配的末尾移动,下次开始匹配时,它会忘记后面的内容。而且碰巧的是,不支持动态的后置检查,所以您不能检查“这个单词是否已经出现在这个匹配位置之前”。但是,您可以做的是用regexp的每次执行替换一个单词(因为这样您就可以始终在字符串的开头锚定)。因此,您要做的是运行以下regexp,只要它替换了某些内容。

代码语言:javascript
复制
s/^.*?\K(?!UNIQUE:)\b(\w+)\b(?=(?:(?!\b\1\b).)*$)/UNIQUE:\1/s
票数 5
EN

Stack Overflow用户

发布于 2009-11-04 02:35:43

注意,您需要替换操作的边界;否则,一个唯一的apple可能与一个非唯一的cranapple发生冲突,例如。

代码语言:javascript
复制
use strict;
use warnings;
use File::Slurp qw(read_file);

my %words;
my $content = read_file(shift @ARGV);
$words{$_} ++ for split /[\s\W]+/, $content;
my @uniq = grep { $words{$_} == 1 and length } keys %words;
$content =~ s/\b$_\b/UNIQUE:$_/g for @uniq;
print $content;
票数 2
EN

Stack Overflow用户

发布于 2009-11-03 09:28:13

我不知道为什么“柠檬”是唯一的,但我假设它只是一个单词的出现,下面是一个awk脚本

代码语言:javascript
复制
awk '{
 for(i=1;i<=NF;i++){
    words[$i]++
    if( words[$i] > 1){   delete words[$i]  }
 }
 a[++d]=$0
}END{
 for(i=1;i<=d;i++){
    m=split(a[i],t," ")
    for(k=1;k<=m;k++){
        if ( t[k] in words ) {
            t[k]="UNIQUE:"t[k]
        }
    }
    for(w=1;w<=d;w++){
        printf "%s ",t[w] 
    }
    print ""
 }
}' file

输出

代码语言:javascript
复制
$ more file
watermelon banana
apple pear pineapple orange mango
strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon

$ ./shell.sh
watermelon banana
apple UNIQUE:pear pineapple orange mango
UNIQUE:strawberry cherry
kiwi pineapple lemon cranberry watermelon
orange plum cherry
kiwi banana plum
mango cranberry apple
lemon
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1665915

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档