首页 > 解决方案 > 使用正则表达式创建子集

问题描述

我有以下维度元素列表(不完整,实际上它更长):

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_"前缀的每个元素。

标签: regexperl

解决方案


问题是+贪婪只是为了匹配整个模式。其中[0-9]+不匹配所有后续数字,但仅匹配其余模式的所有数字。

捕获模式的可变部分 ( [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)/;
}

我们得到

在 Ktr_12345_180 中得到了 Ktr_1234
在 Ktr_12345_1130 中得到了 Ktr_12345
在 Ktr_12345_160 中得到了 Ktr_1234

匹配1234叶子5以满足前瞻的“不是_180”作为1234.

为了调整这一点,我们需要数据细节,这个问题似乎允许两种可能性

  • _如样本数据所示,如果总是有跟随者,则只需_在前瞻之前包含

    /Ktr_[0-9]+_(?!180|160)/
    

    现在需要匹配所有数字之前的内容_。这也“强制”了_那里

  • 如果我们按照文中所说的

    所有以前缀“Ktr_”开头但没有后缀 _160 或 _180 的元素

    那么后面可能没有任何东西Ktr_12345(例如),或者至少没有_

    在这种情况下,只强制匹配所有连续的数字

    /Ktr_[0-9]++(?!_180|_160)/
    

    extra+尽可能多地匹配其前面的子模式,而不管整个模式中接下来的内容是什么;它以所有格量词的名义出现


推荐阅读