我有以下维度元素列表(不完整,实际上要长得多):
Ktr_12345_180
Ktr_12345_160
Ktr_12345_1130
Kst_12345_180
Kst_12345_112
Kst_12345_120
Kst_12345_160
我的目标是在Jedox 2019.1 Subset-Editor中创建元素的子集。
子集应包含所有以前缀"Ktr_"
开头的元素,但不带有后缀_160
或_180
我已经构建了一个正则表达式(Ktr_)+[0-9]+(_180|_160)
,用于标识不需要的元素。
现在我必须将其反转。据我所知,没有用于反转正则表达式的本机功能,对吧?
因此,我尝试通过使用否定的超前行为来做到这一点:(Ktr_)+[0-9]+(?!(_180|_160))
这根本不起作用。我尝试了各种形状,但没有达到目标...
我希望正则表达式能够提供所需的元素。相反,它仅显示每个以"Ktr_"
作为前缀的元素。
答案 0 :(得分:4)
问题在于+
贪婪的程度只在于它满足整个模式的匹配;在[0-9]+
中,它与 all 后面的数字不匹配,但仅与所有匹配,因此其余模式也匹配。
捕获模式([0-9]+
)的可变部分并打印出来以查看
my @ary = qw(
Ktr_12345_180
Ktr_12345_160
Ktr_12345_1130
Kst_12345_180
);
for (@ary) {
say "got $1 in $_" if /(Ktr_[0-9]+)(?!_180|_160)/;
}
我们得到
got Ktr_1234 in Ktr_12345_180 got Ktr_12345 in Ktr_12345_1130 got Ktr_1234 in Ktr_12345_160
匹配1234
会使5
满足1234
之后的先行的“ not _180”要求。
要解决此问题,我们需要数据详细信息,问题似乎允许两种可能性
如果像样本数据所示的那样总是跟随_
,则只需在前瞻之前添加_
/Ktr_[0-9]+_(?!180|160)/
现在要求在_
之前匹配所有数字。这也“强制”了_
如果我们按照文字所说
所有以前缀“ Ktr_”开头但不具有后缀_160或_180的元素
那么Ktr_12345
之后可能没有任何东西,或者至少没有_
在这种情况下,仅强制匹配所有连续的数字
/Ktr_[0-9]++(?!_180|_160)/
其中多余的+
使其前一个子模式尽可能地匹配,而不管整个模式中的后续情况如何;它以possesive quantifiers
答案 1 :(得分:1)
另一种方法是匹配模式,然后对后面的负向求反。
尝试一下
$ cat paul.txt
Ktr_12345_180
Ktr_12345_160
Ktr_12345_1130
Kst_12345_180
Kst_12345_112
Kst_12345_120
Kst_12345_160
$ perl -lne ' print if /(Ktr_).+?(?<!_180|_160)\b/ ' paul.txt
Ktr_12345_1130
$ perl -lne ' print if /(Ktr_)+[0-9]+.+?(?<!_180|_160)\b/ ' paul.txt
Ktr_12345_1130
$
答案 2 :(得分:0)
您需要的正确正则表达式是这个
\bKtr_[0-9]+_(?!1[68]0\b)[0-9]+\b
在正则表达式周围的\b
字边界确保它不会在较大的文本中提供部分匹配,并且(?!1[68]0\b)
是拒绝160
或180
,其余模式与您的相似。另外,除非您需要一个小组,否则您无需将第一部分写为(Ktr_)+
,这也将使Ktr_
的整个部分进行一次或多次,而查看样本不会认为您想。因此,我仅将其更改为简单的Ktr_
,但如果确实有效且确实需要,请通过将Krt_
替换为(Ktr_)+
答案 3 :(得分:0)
您可以将所有格量词与附加的+
配合使用,以确保[0-9]+
匹配出现的数字,并且在匹配失败时不尝试回溯。
(Ktr_)+[0-9]++(?!(_180|_160))
Possessive quantifiers从Perl 5.10开始可用,或者在此之前使用independent subexpression语法。