Создание подмножества с помощью регулярного выражения - PullRequest
2 голосов
/ 02 апреля 2019

У меня следующий список размерных элементов (не полный, на самом деле он намного длиннее):

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_" в качестве префикса.

Ответы [ 4 ]

4 голосов
/ 02 апреля 2019

Проблема в том, что + является жадным настолько, насколько он соответствует целому шаблону; в [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)/;
}

и мы получим

got Ktr_1234   in Ktr_12345_180
got Ktr_12345   in Ktr_12345_1130
got Ktr_1234   in Ktr_12345_160

Соответствие 1234 оставляет 5, чтобы удовлетворять прогнозируемое «не _180» как следующее после 1234.

Чтобы исправить это, нам нужны детали данных, и вопрос, по-видимому, дает две возможности

  • Если всегда есть _, как следует из данных выборки, просто включите _ перед просмотром

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

    что теперь требует сопоставления всех цифр до _. Это также "усиливает" _ там

  • Если мы следуем тому, что написано в тексте

    все элементы, начинающиеся с префикса "Ktr_", но без суффикса _160 или _180

    тогда после Ktr_12345 (например) может не быть ничего или, по крайней мере, _

    В этом случае требуется только сопоставление всех последовательных цифр

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

    , где дополнительный + максимально соответствует своему предшествующему подшаблону, независимо от того, что следует далее во всем шаблоне; он идет под названием позитивных квантификаторов

1 голос
/ 03 апреля 2019

Другой способ состоит в том, чтобы сопоставить шаблон и затем отрицать отрицательный взгляд назад.

Попробуйте это

$ 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
$
0 голосов
/ 02 апреля 2019

Вы можете использовать собственнический квантификатор с дополнительным +, чтобы гарантировать, что [0-9]+ соответствует столько цифр, сколько имеется, и не пытается вернуться в обратном порядке, если совпадение не удалось.

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

Притяжательные квантификаторы доступны начиная с Perl 5.10 или ранее с синтаксисом независимое подвыражение .

0 голосов
/ 02 апреля 2019

Правильное регулярное выражение, которое вам нужно, это

\bKtr_[0-9]+_(?!1[68]0\b)[0-9]+\b

Здесь \b границы слов вокруг регулярного выражения гарантируют, что он не дает частичного совпадения в большом тексте, а (?!1[68]0\b) - это отрицательный взгляд вперед, необходимый для отклонения строк, которые являются 160 или 180 и остальной частью шаблон похож на ваш. Кроме того, если вам не нужна группа, вам не нужно писать первую часть как (Ktr_)+, а также это позволит Ktr_ целиком один или несколько раз, что, глядя на ваши образцы, не сочтет нужным. Поэтому я изменил его на простой Ktr_, но в случае, если он был действительным и действительно необходим, оставьте его, заменив Krt_ на (Ktr_)+

Демо

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...