1

我正在尝试使用 XDCR 将某些文档排除在传输到 ES 之外。我有以下过滤 ABCD 和 IJ 的正则表达式

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

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

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

在此处输入图像描述

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

编辑:
如果我想选择不包含 ABCDE 和 ABCHIJ 的所有内容怎么办。
我试过了

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

4

2 回答 2

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());
    }
}
于 2018-02-07T03:45:18.687 回答
1

编辑:

对不起,再看下去,这个方法是无效的。例如,[^B] 允许 A 通过,让 AABCD 溜走(因为它首先会匹配 AA,然后将 BCD 与 [^A] 匹配。请忽略此帖子。

此处的演示显示以下方法无效


忽略这一点
您可以使用 posix 风格的技巧来排除单词。
下面是排除ABCDIJ
您可以从中了解模式。
基本上,您将所有第一个字母作为交替列表中的第一个放入否定类,然后 以单独的交替
处理每个单词。

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

演示

展开

 ^ 
 (?:
      [^AI]+ 
   |  
      (?:                     # Handle 'ABCD`
           A
           (?: [^B] | $ )
        |  AB
           (?: [^C] | $ )
        |  ABC
           (?: [^D] | $ )
      )
   |  
      (?:                     # Handle 'IJ`
           I
           (?: [^J] | $ )
      )
 )+
 $
于 2016-08-16T17:54:20.857 回答