2016-08-16 20 views
1

Я пытаюсь исключить некоторые документы из транспорта в ES с помощью XDCR. У меня есть следующее регулярное выражение, фильтрующее ABCD и IJCouchbase xdcr regex - Как исключить ключи с помощью регулярных выражений?

https://regex101.com/r/gI6sN8/11

Теперь я хочу использовать это регулярное выражение в XDCR фильтрации

^((ABCD |?!. IJ)). $

enter image description here

Как исключить ключи с помощью регулярных выражений?

EDIT:
Что делать, если я хочу, чтобы выбрать все, что не содержит ABCDE и ABCHIJ.
Я попытался

https://regex101.com/r/zT7dI4/1

+0

Acc. на http://developer.couchbase.com/documentation/server/current/xdcr/xdcr-create.html, вы должны иметь возможность использовать lookaheads, как и для jS. –

ответ

1

редактировать:

К сожалению, после того, как дальше, глядя на него, этот метод является недействительным. Например, [^ B] позволяет А както, позволяя AABCD ускользнуть (так как она будет соответствовать АА в первом, а затем совпадают BCD с [^ A]. Не обращайте внимания на этот пост.

Demo here shows below method is invalid


(невнимание это)
Вы можете использовать трюк в стиле POSIX, чтобы исключить слова.
Ниже исключить ABCD и IJ.
Вы получаете представление об этом шаблоне.
В принципе, вы кладете все первых букв в негативный класс
как первые в списке чередованию, затем обрабатывать каждое слово
в отдельном чередовании.

^(?:[^AI]+|(?:A(?:[^B]|$)|AB(?:[^C]|$)|ABC(?:[^D]|$))|(?:I(?:[^J]|$)))+$

Demo

Expanded

^
(?: 
     [^AI]+ 
    | 
     (?:      # Handle 'ABCD` 
      A 
      (?: [^B] | $) 
     | AB 
      (?: [^C] | $) 
     | ABC 
      (?: [^D] | $) 
    ) 
    | 
     (?:      # Handle 'IJ` 
      I 
      (?: [^J] | $) 
    ) 
)+ 
$ 
+0

если я хочу выбрать все, что не содержит ABCDE и ABCHIJ. Я пытался принять вашу технику, но безуспешно. Можете ли вы порекомендовать решение? https://regex101.com/r/zT7dI4/1 Обновление исходного вопроса. – Jeb

+0

Извините, после дальнейшего изучения этого метода этот метод недействителен. Например, '[^ B]' разрешает прохождение A, позволяя пропустить «AABCD» (поскольку оно сначала будет соответствовать «AA», а затем сопоставить BCD с «[^ A]». Пожалуйста, не обращайте внимания на это сообщение. Я оставлю это на день или два, затем я удалю его. Спасибо! – sln

+0

Спасибо. Можете добавить в добавленную вами демонстрацию (https://regex101.com/r/gR5jW4/1), что может get by? – Jeb

1

Надеюсь, в один прекрасный день будет встроенная поддержка для инвертирования выражения соответствия. В то же время, вот Java 8-программа, которая генерирует регулярные выражения для перевернутого сопоставления префикса, используя базовые функции регулярного выражения, поддерживаемые фильтром Couchbase XDCR.

Это должно работать до тех пор, пока ваши ключевые префиксы как-то ограничены от остальной части ключа. Обязательно включите разделитель во вводе при изменении этого кода.

Пример выходных данных red:, reef:, green: является:

^([^rg]|r[^e]|g[^r]|re[^de]|gr[^e]|red[^:]|ree[^f]|gre[^e]|reef[^:]|gree[^n]|green[^:]) 

Файл: NegativeLookaheadCheater.java

import java.util.*; 
import java.util.stream.Collectors; 

public class NegativeLookaheadCheater { 

    public static void main(String[] args) { 
     List<String> input = Arrays.asList("red:", "reef:", "green:"); 
     System.out.println("^" + invertMatch(input)); 
    } 

    private static String invertMatch(Collection<String> literals) { 
     int maxLength = literals.stream().mapToInt(String::length).max().orElse(0); 

     List<String> terms = new ArrayList<>(); 
     for (int i = 0; i < maxLength; i++) { 
      terms.addAll(terms(literals, i)); 
     } 

     return "(" + String.join("|", terms) + ")"; 
    } 

    private static List<String> terms(Collection<String> words, int index) { 
     List<String> result = new ArrayList<>(); 
     Map<String, Set<Character>> prefixToNextLetter = new LinkedHashMap<>(); 

     for (String word : words) { 
      if (word.length() > index) { 
       String prefix = word.substring(0, index); 
       prefixToNextLetter.computeIfAbsent(prefix, key -> new LinkedHashSet<>()).add(word.charAt(index)); 
      } 
     } 

     prefixToNextLetter.forEach((literalPrefix, charsToNegate) -> { 
      result.add(literalPrefix + "[^" + join(charsToNegate) + "]"); 
     }); 

     return result; 
    } 

    private static String join(Collection<Character> collection) { 
     return collection.stream().map(c -> Character.toString(c)).collect(Collectors.joining()); 
    } 
}