【问题标题】:Within a JSON string how does one for all string values of a given key replace any occurrence of a specific substring?在 JSON 字符串中,给定键的所有字符串值如何替换任何出现的特定子字符串?
【发布时间】:2022-01-21 05:23:43
【问题描述】:

我正在寻找一种将 JSON 中的给定字符串替换为另一个字符串的方法,但仅限于某个键。例如,假设我有以下 JSON,data:

[
    {
        "name": "please, I said please",
        "title": "Test One",
        "more": [
            {
                "name": "another name",
                "title": "please write something"
            }
        ]
    },
    {
        "name": "testTwo",
        "title": "Test Two"
    },
    {
        "name": "testThree",
        "title": "Test Three"
    },
    {
        "name": "testFour",
        "title": "Test Four"
    }
]

比如说,我想用“could you”替换所有出现的“please”一词。在这个例子中,我只想替换整个单词。现在,我有一个可行的例子:

const wordToReplace = "please"

const jsonString = JSON.stringify(data)
const reg = new RegExp(`\\b${wordToReplace}\\b`, 'gi) // whole words only and case insensitive
const dataReplaced = jsonString.replace(reg, function () {
  return 'could you'
}

console.log(JSON.parse(dataReplaced))

鉴于上述代码,“请”一词在所有出现时都将替换为“您可以”。但是,只有当键是“标题”时,我才想替换单词。现在,它将为任何给定的键替换它(例如,在键是“名称”和“标题”的第一个实例中)。

还有一点需要注意的是,从示例中可以看出,JSON 可以具有不同数量的嵌套属性。它并不总是相同的嵌套对象。

另外,我在 replace 方法中添加函数的原因是因为我在尝试指定键的方法。

【问题讨论】:

  • 我不建议为此使用 .replace。 (不是我的反对票)
  • @0stone0 在这种情况下你有什么建议?
  • 或者像jq这样的命令行工具,或者只是花哨的循环或者reduce
  • 如果嵌套对象的数量可以不同并且并不总是相同,我将如何循环对象?我试过递归地这样做,但无法让它发挥作用。
  • @Adam ...无需重新发明轮子。 JSON 方法,parsestringify 都能够处理额外提供的回调,称为 reviverreplacer。此回调允许访问当前处理的条目的keyvalue。因此,人们可以控制将返回哪种value

标签: javascript regex replace stringify jsonparser


【解决方案1】:

无需重新发明轮子。 JSON 方法,JSON.parseJSON.stringify 都能够处理额外提供的回调,称为 ...

const sampleJSON = '[{"name":"please, I said please","title":"Test One","more":[{"name":"another name","title":"please write something"}]},{"name":"testTwo","title":"Test Two"},{"name":"testThree","title":"Test Three"},{"name":"testFour","title":"Test Four"}]'

const sampleData = JSON.parse(sampleJSON, (key, value) => {
  const regX = (/\bplease\b/gmi);

  return (key === 'title' && regX.test(value))
    ? value.replace(regX, 'could you')
    : value;
});

console.log({ sampleData });
console.log('JSON.parse(sampleJSON) ...', JSON.parse(sampleJSON));
.as-console-wrapper { min-height: 100%!important; top: 0; }

const sampleData = [{
  name: 'please, I said please',
  title: 'Test One',
  more: [{
    name: 'another name',
    title: 'please write something',
  }],
}, {
  name: 'testTwo',
  title: 'Test Two',
}, {
  name: 'testThree',
  title: 'Test Three',
}, {
  name: 'testFour',
  title: 'Test Four',
}];

const sampleJSON = JSON.stringify(sampleData, (key, value) => {
  const regX = (/\bplease\b/gmi);

  return (key === 'title' && regX.test(value))
    ? value.replace(regX, 'could you')
    : value;
});

console.log({ sampleJSON });
console.log("JSON.stringify(sampleData) ...", { stringifed: JSON.stringify(sampleData)});
.as-console-wrapper { min-height: 100%!important; top: 0; }

【讨论】:

    【解决方案2】:

    我不建议在转换为字符串的 json 上使用 replace

    相反,我会递归循环遍历数组/对象并在需要时更改值

    简单示例:

    const data = [{"name": "please, I said please", "title": "Test One", "more": [{"name": "another name", "title": "please write something"} ] }, {"name": "testTwo", "title": "Test Two"}, {"name": "testThree", "title": "Test Three"}, {"name": "testFour", "title": "Test Four"} ];
    const regx = new RegExp(`\\bplease\\b`, 'gi');
    
    function replace(obj) {
        for (var k in obj) {
            if (typeof obj[k] == "object" && obj[k] !== null) {
                replace(obj[k]);
            } else if (k === 'title') {
                obj[k] = obj[k].replaceAll(regx, 'could you');
            }
        }
        return obj;
    }
    
    const result = data.map(o => replace(o));
    console.log(result);

    【讨论】:

    • 谢谢。我将如何在 replaceAll 方法中添加正则表达式?
    • 将硬编码的 replaceall 更改为您的正则表达式
    猜你喜欢
    • 1970-01-01
    • 2019-04-12
    • 2012-09-04
    • 2020-10-04
    • 2020-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多