给定由:
分隔的标识符字符串,是否可以构造正则表达式以将唯一标识符提取到另一个字符串中,也用:
分隔?
如何使用正则表达式实现此目的?我试过s/(:[^:])(.*)\1/$1$2/g
没有运气,因为(.*)
贪婪并跳到$1
的最后一场比赛。
示例:a:b:c:d:c:c:x:c:c:e:e:f
应该提供a:b:c:d:x:e:f
注意:我在perl编码,但我非常感谢使用正则表达式。
答案 0 :(得分:9)
在支持无限重复内部的.NET中,你可以搜索
(?<=\b\1:.*)\b(\w+):?
并用空字符串替换所有匹配项。
Perl(至少Perl 5)只支持固定长度的lookbehinds,所以你可以尝试以下(使用lookahead,结果略有不同):
\b(\w+):(?=.*\b\1:?)
如果用空字符串替换它,则将删除重复条目的所有先前重复; last 将保留。而不是
a:b:c:d:x:e:f
你会得到
a:b:d:x:c:e:f
如果可以,您可以使用
$subject =~ s/\b(\w+):(?=.*\b\1:?)//g;
<强>解释强>
第一个正则表达式:
(?<=\b\1:.*)
:检查您是否可以匹配反向引用号码的内容。 1,然后是冒号,在字符串之前的某处。
\b(\w+):?
:匹配一个标识符(从单词边界到下一个:
),可选地后跟冒号。
第二个正则表达式:
\b(\w+):
:匹配标识符和冒号。
(?=.*\b\1:?)
:然后检查你是否可以在字符串中的前面某处匹配相同的标识符,可选地后面跟一个冒号。
答案 1 :(得分:2)
退房:http://www.regular-expressions.info/duplicatelines.html
在考虑任何正则表达式时始终是一个有用的网站。
答案 2 :(得分:1)
$str = q!a:b:c:d:c:c:x:c:c:e:e:f!;
1 while($str =~ s/(:[^:]+)(.*?)\1/$1$2/g);
say $str
输出:
a:b:c:d:x:e:f
答案 3 :(得分:0)
如果标识符已排序,您可以使用lookahead / lookbehind进行排序。如果它们不是,那么这超出了正则表达式的计算能力。现在,仅仅因为正式正则表达式不可能并不意味着如果你使用一些perl特定的正则表达式功能是不可能的,但如果你想保持你的正则表达式可移植,你需要用支持变量的语言来描述这个字符串。
答案 4 :(得分:0)
这是一个awk版本,不需要正则表达式。
$ echo "a:b:c:d:c:c:x:c:c:e:e:f" | awk -F":" '{for(i=1;i<=NF;i++)if($i in a){continue}else{a[$i];printf $i}}'
abcdxef
拆分“:”上的字段,浏览拆分字段,将元素存储在数组中。检查是否存在,如果存在,请跳过。否则打印出来。您可以轻松地将其转换为Perl代码。