如何使用python正则表达式匹配RabbitMQ主题交换的路由密钥和绑定模式?

mm9b1k5b  于 2022-11-08  发布在  RabbitMQ
关注(0)|答案(4)|浏览(160)

我基本上是在RabbitMQ上工作。我正在写一个python代码,其中我试图查看在主题交换的情况下,路由键是否与绑定模式匹配。我遇到了这个链接-https://www.rabbitmq.com/tutorials/tutorial-five-java.html,它说-“然而,有两个重要的绑定键特殊情况:


* (star) can substitute for exactly one word.

# (hash) can substitute for zero or more words.

那么我如何匹配消息的路由关键字和队列的绑定模式呢?例如,消息的路由关键字是“my.routing.key”,而队列绑定到主题交换的绑定模式是“my.#.*"。一般来说,我如何匹配主题交换的这些字符串模式,最好是使用python正则表达式。

inkz8wg9

inkz8wg91#

这几乎是节点lib amqp-match的直接端口:

import re

def amqp_match(key: str, pattern: str) -> bool:
    if key == pattern:
        return True
    replaced = pattern.replace(r'*', r'([^.]+)').replace(r'#', r'([^.]+.?)+')
    regex_string = f"^{replaced}$"
    match = re.search(regex_string, key)
    return match is not None
knpiaxh1

knpiaxh12#

我有一些Java代码,如果可以帮助您的话

Pattern toRegex(String pattern) {
    final String word = "[a-z]+";

    // replace duplicate # (this makes things simpler)
    pattern = pattern.replaceAll("#(?:\\.#)+", "#");

    // replace *
    pattern = pattern.replaceAll("\\*", word);

    // replace #

    // lone #
    if ("#".equals(pattern)) return Pattern.compile("(?:" + word + "(?:\\." + word + ")*)?");

    pattern = pattern.replaceFirst("^#\\.", "(?:" + word + "\\.)*");
    pattern = pattern.replaceFirst("\\.#", "(?:\\." + word + ")*");

    // escape dots that aren't escapes already
    pattern = pattern.replaceAll("(?<!\\\\)\\.", "\\\\.");

    return Pattern.compile("^" + pattern + "$");
}

也许有人能把它翻译成python。

guz6ccqo

guz6ccqo3#

我们使用这个模式将RabbitMQ模式转换为正则表达式:

from typing import Pattern

def convert(pattern: str) -> Pattern:
    pattern = (
        pattern
        .replace('*', r'([^.]+)')
        .replace('.#', r'(\.[^.]+)*')
        .replace('#.', r'([^.]+\.)*')
    )
    return re.compile(f"^{pattern}$")
63lcw9qa

63lcw9qa4#

我正在使用这个java函数:

public boolean matchRoutingPatterns(String routingTopic, String routingKey)
{
    // replace duplicates
    routingTopic = routingTopic.replaceAll("#(?:\\.#)+", "#").replaceAll("([#*])\\1{2,}", "$1");
    routingKey   = routingKey.replaceAll("#(?:\\.#)+", "#").replaceAll("([#*])\\1{2,}", "$1");

    String[] routingTopicPath = Strings.splitList( routingTopic.replace('.', ','));
    String[] routingKeyPath   = Strings.splitList( routingKey.replace('.', ','));

    int i=0;
    int j=0;
    while (i<routingTopicPath.length && j<routingKeyPath.length)
    {
        if ("#".equals(routingTopicPath[i]) || "#".equals(routingKeyPath[j]))
        {
            if (routingTopicPath.length-i > routingKeyPath.length-j)
                { i++; }
            else
            if (routingTopicPath.length-i < routingKeyPath.length-j)
                { j++; }
            else
                { i++; j++; }
        }
        else
        if ("*".equals(routingTopicPath[i]) || "*".equals(routingKeyPath[j]))
        {
            i++; j++;
        }
        else
        if (routingTopicPath[i].equals(routingKeyPath[j]))
        {
            i++; j++;
        }
        else
        {
            return false;
        }
    }

    return true;
}

相关问题