How to manipulate leaves of a JSON tree

前端 未结 1 1179
挽巷
挽巷 2021-01-23 18:22

I want to replace rare words with _RARE_ in a JSON tree using JAVA.

My rareWords list contains

late  
populate
convicts


        
相关标签:
1条回答
  • 2021-01-23 18:37

    Here's a straight forward approach in C++:

    #include <fstream>
    #include "JSON.hpp"
    #include <boost/algorithm/string/regex.hpp>
    #include <boost/range/adaptors.hpp>
    #include <boost/phoenix.hpp>
    
    static std::vector<std::wstring> readRareWordList()
    {
        std::vector<std::wstring> result;
    
        std::wifstream ifs("testcases/rarewords.txt");
        std::wstring line;
        while (std::getline(ifs, line))
            result.push_back(std::move(line));
    
        return result;
    }
    
    struct RareWords : boost::static_visitor<> {
    
        /////////////////////////////////////
        // do nothing by default
        template <typename T> void operator()(T&&) const { /* leave all other things unchanged */ }
    
        /////////////////////////////////////
        // recurse arrays and objects
        void operator()(JSON::Object& obj) const { 
            for(auto& v : obj.values) {
                //RareWords::operator()(v.first); /* to replace in field names (?!) */
                boost::apply_visitor(*this, v.second);
            }
        }
    
        void operator()(JSON::Array& arr) const {
            int i = 0;
            for(auto& v : arr.values) {
                if (i++) // skip the first element in all arrays
                    boost::apply_visitor(*this, v);
            }
        }
    
        /////////////////////////////////////
        // do replacements on strings
        void operator()(JSON::String& s) const {
            using namespace boost;
    
            const static std::vector<std::wstring> rareWords = readRareWordList();
            const static std::wstring replacement = L"__RARE__";
    
            for (auto&& word : rareWords)
                if (word == s.value)
                    s.value = replacement;
        }
    };
    
    int main()
    {
        auto document = JSON::readFrom(std::ifstream("testcases/test3.json"));
    
        boost::apply_visitor(RareWords(), document);
    
        std::cout << document;
    }
    

    This assumes you wanted to do replacements on all string values, and only matches whole strings. You could easily make this case insensitive, match words inside strings etc. by changing the regex or regex flags. Slightly adapted in response to the comments.

    The full code including JSON.hpp/cpp is here: https://github.com/sehe/spirit-v2-json/tree/16093940

    0 讨论(0)
提交回复
热议问题