Couchbase xdcr regex - 如何使用正则表达式排除键?

时间:2016-08-16 16:36:17

标签: regex couchbase xdcr

我试图使用XDCR排除某些文件被传输到ES。 我有以下正则表达式过滤ABCD和IJ

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

现在,我想在XDCR过滤中使用这个正则表达式

^((ABCD?|!IJ))。的$

enter image description here

如何使用正则表达式排除键?

修改
如果我想选择不包含ABCDE和ABCHIJ的所有内容,该怎么办? 我试过了

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

2 个答案:

答案 0 :(得分:1)

编辑

很抱歉,经过进一步查看,此方法无效。例如,[^ B]允许A通过,让AABCD滑过(因为它首先匹配AA,然后将BCD与[^ A]匹配。请忽略此帖子。

Demo here shows below method is invalid

忽视此
您可以使用posix样式技巧来排除单词 以下是排除ABCDIJ 你可以从中得到一种模式。
基本上,您将所有第一个字母放入否定类中 作为交替列表中的第一个,然后处理每个单词
在一个单独的交替。

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

Demo

扩展

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

答案 1 :(得分: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());
    }
}