【问题标题】:What is wrong with this javascript regex string.replace?这个 javascript 正则表达式 string.replace 有什么问题?
【发布时间】:2021-08-10 05:42:15
【问题描述】:

更新:我发现这个问题是因为“字符串化”输出不包含空格或换行符,并且与原始 JSON 不同。

字符串化输出:

{"eventType":"Delivery","mail":{"timestamp":"2021-08-09T20:41:51.515Z","source":"removed@email.com","sourceArn":"arn:aws:ses:us-east-1:1234567890:identity/removed.com","sendingAccountId":"1234567890","messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","destination":["removedl@email.com"],"headersTruncated":false,"headers":[{"name":"From","value":"removed@email.com"},{"name":"To","value":"removed@email.com"},{"name":"Subject","value":"Test"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"7bit"}],"commonHeaders":{"from":["removed@email.com"],"to":["removed@email.com"],"messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","subject":"Test"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["GenericLog"],"ses:source-ip":["123.123.123.123"],"ses:from-domain":["email.com"],"ses:caller-identity":["user1"],"ses:outgoing-ip":["234.234.234.234"]}},"delivery":{"timestamp":"2021-08-09T20:41:52.880Z","processingTimeMillis":1365,"recipients":["removed@email.com"],"smtpResponse":"250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b@email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery","reportingMTA":"a48-108.smtp-out.amazonses.com"}}

原文:

我想从键名中删除 : 并将其替换为以下 JSON 中的 _。 (在tags 部分)

{
    "eventType": "Delivery",
    "mail": {
        "timestamp": "2021-08-09T20:41:51.515Z",
        "source": "removed@email.com",
        "sourceArn": "arn:aws:ses:us-east-1:1234567890:identity/removed.com",
        "sendingAccountId": "1234567890",
        "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b",
        "destination": [
            "removedl@email.com"
        ],
        "headersTruncated": false,
        "headers": [
            {
                "name": "From",
                "value": "removed@email.com"
            },
            {
                "name": "To",
                "value": "removed@email.com"
            },
            {
                "name": "Subject",
                "value": "Test"
            },
            {
                "name": "MIME-Version",
                "value": "1.0"
            },
            {
                "name": "Content-Type",
                "value": "text/plain; charset=UTF-8"
            },
            {
                "name": "Content-Transfer-Encoding",
                "value": "7bit"
            }
        ],
        "commonHeaders": {
            "from": [
                "removed@email.com"
            ],
            "to": [
                "removed@email.com"
            ],
            "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b",
            "subject": "Test"
        },
        "tags": {
            "ses:operation": [
                "SendEmail"
            ],
            "ses:configuration-set": [
                "GenericLog"
            ],
            "ses:source-ip": [
                "123.123.123.123"
            ],
            "ses:from-domain": [
                "email.com"
            ],
            "ses:caller-identity": [
                "user1"
            ],
            "ses:outgoing-ip": [
                "234.234.234.234"
            ]
        }
    },
    "delivery": {
        "timestamp": "2021-08-09T20:41:52.880Z",
        "processingTimeMillis": 1365,
        "recipients": [
            "removed@email.com"
        ],
        "smtpResponse": "250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b@email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery",
        "reportingMTA": "a48-108.smtp-out.amazonses.com"
    }
}

我创建了一个由 AWS Kinesis 调用的 node.js Lambda 函数。它处理上述 JSON 并使用以下代码。我正在调试,所以我只是尝试搜索和替换字符串进行测试:

console.log('Loading function');

exports.handler = async (payload, context) => {

        payload = JSON.stringify(payload);
        payload = payload.replace(/".*:.*":/g, 'replaced');
        
        console.log('Replaced payload:', payload);
};

我已经通过多个代码测试站点运行了正则表达式,它正确地识别了所有 6 次出现的带有 : 的键名。我什至使用过this 测试器,它按预期正确替换了所有6 个字符串。但是,当它在 Lambda 上运行时,我得到以下输出:

Replaced payload: {replaced"a48-108.smtp-out.amazonses.com"}}

我是否遗漏了一些明显的东西,或者这是 Lambda 中发生的一些奇怪的事情?

注意,如果我只是输出未修改的 payload 变量,它会匹配输入 JSON,所以这不是问题。

我有额外的代码,一旦我解决了这个谜题,应该可以成功完成这个任务。但是,如果您可以提供代码以将键名中的 : 替换为 _,那也很棒。

【问题讨论】:

    标签: node.js replace aws-lambda


    【解决方案1】:

    扩展您的更新评论:

    更新:我发现这个问题是因为“字符串化”输出不包含空格或换行符,并且与原始 JSON 不同。

    您可以将以下选项添加到JSON.stringify 以正确格式化字符串化输出。

    JSON.stringify(payload, null, 4);
    

    演示:

    let payload = {"eventType":"Delivery","mail":{"timestamp":"2021-08-09T20:41:51.515Z","source":"removed@email.com","sourceArn":"arn:aws:ses:us-east-1:1234567890:identity/removed.com","sendingAccountId":"1234567890","messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","destination":["removedl@email.com"],"headersTruncated":false,"headers":[{"name":"From","value":"removed@email.com"},{"name":"To","value":"removed@email.com"},{"name":"Subject","value":"Test"},{"name":"MIME-Version","value":"1.0"},{"name":"Content-Type","value":"text/plain; charset=UTF-8"},{"name":"Content-Transfer-Encoding","value":"7bit"}],"commonHeaders":{"from":["removed@email.com"],"to":["removed@email.com"],"messageId":"1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b","subject":"Test"},"tags":{"ses:operation":["SendEmail"],"ses:configuration-set":["GenericLog"],"ses:source-ip":["123.123.123.123"],"ses:from-domain":["email.com"],"ses:caller-identity":["user1"],"ses:outgoing-ip":["234.234.234.234"]}},"delivery":{"timestamp":"2021-08-09T20:41:52.880Z","processingTimeMillis":1365,"recipients":["removed@email.com"],"smtpResponse":"250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b@email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery","reportingMTA":"a48-108.smtp-out.amazonses.com"}};
    
    payload = JSON.stringify(payload, null, 4)
    payload = payload.replace(/".*:.*":/g, 'replaced');
    
    console.log('Replaced payload:', payload);

    【讨论】:

    • 是的,这就解决了问题。我应该担心以这种方式使用正则表达式吗?
    • @Appleoddity 我认为以这种方式使用正则表达式没有任何问题,但意外匹配可能会破坏您的代码。
    【解决方案2】:

    请注意,简单地使用.* 意味着“可以匹配尽可能多的字符”,即它很渴望。您可以添加? 进行延迟匹配,如“尽可能少地匹配”。

    我建议使用/".*?:.*?":/g,因为这基本上意味着“将所有字符移到最近的:,然后将字符移到最近的":”。


    使用递归函数来映射对象,而不是在 JSON 版本上使用 RegExp:

    const data = { "eventType": "Delivery", "mail": { "timestamp": "2021-08-09T20:41:51.515Z", "source": "removed@email.com", "sourceArn": "arn:aws:ses:us-east-1:1234567890:identity/removed.com", "sendingAccountId": "1234567890", "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b", "destination": ["removedl@email.com"], "headersTruncated": false, "headers": [{ "name": "From", "value": "removed@email.com" }, { "name": "To", "value": "removed@email.com" }, { "name": "Subject", "value": "Test" }, { "name": "MIME-Version", "value": "1.0" }, { "name": "Content-Type", "value": "text/plain; charset=UTF-8" }, { "name": "Content-Transfer-Encoding", "value": "7bit" }], "commonHeaders": { "from": ["removed@email.com"], "to": ["removed@email.com"], "messageId": "1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b", "subject": "Test" }, "tags": { "ses:operation": ["SendEmail"], "ses:configuration-set": ["GenericLog"], "ses:source-ip": ["123.123.123.123"], "ses:from-domain": ["email.com"], "ses:caller-identity": ["user1"], "ses:outgoing-ip": ["234.234.234.234"] } }, "delivery": { "timestamp": "2021-08-09T20:41:52.880Z", "processingTimeMillis": 1365, "recipients": ["removed@email.com"], "smtpResponse": "250 2.6.0 <1123bfe-123123b12e12d2c212a-123b12c2e1123-213f312d32c123b@email.amazonses.com> [InternalId=11231247472, Hostname=CO6PR12MB5396.namprd12.prod.outlook.com] 12090 bytes in 0.214, 55.135 KB/sec Queued mail for delivery", "reportingMTA": "a48-108.smtp-out.amazonses.com" } };
    
    function convert(obj) {
        if (typeof obj !== 'object') return obj;
        if (Array.isArray(obj)) return obj.map(convert);
        const result = {};
        for(const key in obj) {
            result[key.replace(/:/g, '_')] = convert(obj[key]);
        }
        return result;
    }
    
    const converted = convert(data);
    console.log(converted);
    console.log(JSON.stringify(converted, null, 4));

    【讨论】:

    • 听起来我们正在做某事。但是,还是有问题。使用新的正则表达式,开始输出如下所示:{replaced{replacedreplacedreplaced[replaced[{replacedreplacedreplacedreplacedreplacedreplacedreplaced
    • 嗯。如果您只想定位键,"[^"]*": 应该可以工作,只要您的键中没有双引号。或者,创建一个递归函数以使用更改的键映射您的对象。
    • 是的。我认为最可靠的解决方案是使用递归函数。我理解这个概念,但仍在试图弄清楚如何操作 JSON 对象。愿意给我一个代码示例吗?谢谢!
    • @Appleoddity 我已经用一个适用于常规对象而不是 JSON 字符串的函数更新了我的答案。
    • 是的。这完美无缺。我有点不清楚某些语法的作用(我缺乏 javascript 知识),所以我会继续解读它。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多