给定一个由 分隔的标识符字符串:
,是否可以构造一个正则表达式将唯一标识符提取到另一个字符串中,也由 分隔:
?
如何使用正则表达式来实现这一点?我试过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 进行编码,但我非常感谢为此使用正则表达式。
给定一个由 分隔的标识符字符串:
,是否可以构造一个正则表达式将唯一标识符提取到另一个字符串中,也由 分隔:
?
如何使用正则表达式来实现这一点?我试过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 进行编码,但我非常感谢为此使用正则表达式。
在支持无限重复的.NET中,您可以搜索
(?<=\b\1:.*)\b(\w+):?
并用空字符串替换所有匹配项。
Perl(至少 Perl 5)只支持固定长度的lookbehinds,所以你可以尝试以下方法(使用lookahead,结果略有不同):
\b(\w+):(?=.*\b\1:?)
如果将其替换为空字符串,则所有先前重复的重复条目都将被删除;最后一个将保留。所以而不是
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:?)
:然后检查是否可以匹配相同的标识符,可选地后跟冒号,在字符串的前面某处。
查看:http ://www.regular-expressions.info/duplicatelines.html
在考虑任何正则表达式时总是一个有用的站点。
$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
如果标识符已排序,您可以使用前瞻/后瞻来完成。如果不是,那么这超出了正则表达式的计算能力。现在,仅仅因为正式的正则表达式不可能,并不意味着如果您使用某些 perl 特定的正则表达式功能就不可能,但是如果您想让您的正则表达式保持可移植性,您需要用支持变量的语言来描述这个字符串。
这是一个 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 代码。