如何使用正则表达式捕获 json 中列表的值

问题描述 投票:0回答:2

我有一个 json 部分,其中包含以下内容:
{"tokenType":"电子邮件","tokenList":["token1","token2","token3","token4"]}

我有一个 flink 作业正在记录从 kafka 接收的有效负载,我需要在日志中屏蔽这些令牌值(电子邮件/电话号码)。为此,我们使用一个实用程序,它将屏蔽所有捕获组的前 x 个字符(从索引 1 开始)。

我的问题是,当列表长度可变时,我找不到可以捕获所有这些标记的正则表达式。

我可以编写可以捕获整个列表的正则表达式,但问题是整个匹配将被视为捕获组,并且前 x 个字符将被屏蔽。 我希望我的日志看起来像这样,对于 x = 3:
{"tokenType":"电子邮件","tokenList":["***en1","***en2","***en3","***en4"]}

我需要我的正则表达式来捕获这些标记的值。

java regex apache-kafka apache-flink
2个回答
0
投票

如果您正在处理一对多映射,您可能希望通过

flatMap()
函数来完成此操作,以支持从单个元素创建多个元素。由于您的有效负载已经接受基于 JSON 的字符串,因此您可以将其解析为结构化 JSON 对象,然后提取所需的元素并将其发送到下游。

类似:

// Function to take in a single JSON string and output multiple string elements
class TokenMaskingFunction: FlatMapFunction<String, String>{
    override fun flatMap(input: String, collector: Collector<String>) {
        try {
            // Construct your JSON node
            val structuredJson: JsonNode = mapper.readTree(input)
    
            // Capture your tokens
            val tokens: JsonNode = structuredJson.get("tokenList")
            if (tokens.isArray) {
                for (token in tokens) {
                    // Extract and mask your token before sending downstream
                    val maskedToken = maskFunction(token.toString())
                    collector.collect(maskedToken)
                }
            }
        } catch (e: Exception) {
            // Handle accordingly / log / ignore
        }
    }

    private fun mask(token: String): String { 
        // Do your masking here
    }

    companion object {
        // Define some static JSON parser here (static is important)
        val mapper = ObjectMapper()
    }
}

然后您只需在从 JSON 字符串源映射后使用它即可:

streamEnv
    .fromSource(yourJsonStringSource)
    .flatMap(TokenMaskingFunction())
    .process(...)

0
投票

我使用 Pattern 类做了一个粗略的解决方案。它不是很有效,但适用于给定的示例。

    public static void main(String[] args) {
        String val = " {\"tokenType\":\"email\",\"tokenList\":[\"token1\",\"token2\",\"token3\",\"token4\"]}";
        Pattern p = Pattern.compile("(?:\\G(?!^)|\"tokenList\":\\[)\"(?<elem>[^\"]*)\",?");
        Matcher m = p.matcher(val);
        int n  = 3;
        StringBuilder builder = new StringBuilder();
        while (m.find()) {
            String elem = m.group("elem");
            if (elem != null) {
                m.appendReplacement(builder, m.group().replace(elem, "*".repeat(n).concat(elem.substring(n))));
            }
        }
        m.appendTail(builder);
        System.out.println(builder);
    }
© www.soinside.com 2019 - 2024. All rights reserved.