【问题标题】:Couchbase xdcr regex - How do I exclude keys using regex?Couchbase xdcr 正则表达式 - 如何使用正则表达式排除键?
【发布时间】:2018-02-07 11:45:18
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

标签: regex couchbase xdcr


【解决方案1】:

编辑:

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

Demo here shows below method is invalid


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

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

Demo

展开

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

【讨论】:

  • 如果我想选择不包含 ABCDE 和 ABCHIJ 的所有内容。我试图采用你的技术,但没有成功。你能推荐一个解决方案吗? regex101.com/r/zT7dI4/1更新原始问题。
  • 对不起,再看下去,这个方法是无效的。例如,[^B] 允许 A 通过,让 AABCD 溜走(因为它首先会匹配 AA,然后匹配 BCD 和 [^A]。请忽略此帖子。我会留下它一两天,然后我将其删除。谢谢!
  • 谢谢。能不能在你添加的demo中添加(regex101.com/r/gR5jW4/1)能得到什么?
  • @Jeb - 添加了一个更新,其中包含显示此方法无效的链接。
【解决方案2】:

希望有一天会内置支持反转匹配表达式。同时,这里有一个 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-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    • 2015-12-29
    相关资源
    最近更新 更多