Java 如何操作JSON树的叶子

Java 如何操作JSON树的叶子,java,json,data-structures,tree,Java,Json,Data Structures,Tree,我想使用JAVA将JSON树中的稀有词替换为\u稀有词 我的珍品清单包含 late populate convicts 下面是JSON ["S", ["PP", ["ADP", "In"], ["NP", ["DET", "the"], ["NP", ["ADJ", "late"], ["NOUN", "1700<s"]]]], ["S", ["NP", ["ADJ", "British"], ["NOUN", "convicts"]], ["S", ["VP", ["VERB",

我想使用JAVA将JSON树中的稀有词替换为
\u稀有词

我的珍品清单包含

late  
populate
convicts
下面是JSON

["S", ["PP", ["ADP", "In"], ["NP", ["DET", "the"], ["NP", ["ADJ", "late"], ["NOUN", "1700<s"]]]], ["S", ["NP", ["ADJ", "British"], ["NOUN", "convicts"]], ["S", ["VP", ["VERB", "were"], ["VP", ["VERB", "used"], ["S+VP", ["PRT", "to"], ["VP", ["VERB", "populate"], ["WHNP", ["DET", "which"], ["NOUN", "colony"]]]]]], [".", "?"]]]]
被替换为

["ADJ","_RARE_"]
到目前为止,我的代码如下所示:

我递归地遍历树,一旦找到稀有词,我就创建一个新的JSON数组,并尝试用它替换现有树的节点。请参阅下面的
//这不起作用
,这就是我被卡住的地方。除此功能外,树保持不变

public static void traverseTreeAndReplaceWithRare(JsonArray tree){   

        //System.out.println(tree.getAsJsonArray()); 

        for (int x = 0; x < tree.getAsJsonArray().size(); x++)
        {
            if(!tree.get(x).isJsonArray())
            {
                if(tree.size()==2)
                {   
                //beware it will get here twice for same word
                 String word= tree.get(1).toString();  
                 word=word.replaceAll("\"", ""); // removing double quotes

                 if(rareWords.contains(word))
                 {
                 JsonParser parser = new JsonParser();                   

                             //This works perfectly 
                             System.out.println("Orig:"+tree);
                 JsonElement jsonElement = parser.parse("["+tree.get(0)+","+"_RARE_"+"]");

                 JsonArray newRareArray = jsonElement.getAsJsonArray();

                             //This works perfectly 
                             System.out.println("New:"+newRareArray);

                 tree=newRareArray; // this Doesn't work
                 }                 

                }               
                continue;   
            }
            traverseTreeAndReplaceWithRare(tree.get(x).getAsJsonArray());
        }
    }

在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;
}
#包括
#包括“JSON.hpp”
#包括
#包括
#包括
静态std::vector readRareWordList()
{
std::向量结果;
std::wifstream ifs(“testcases/rarewords.txt”);
std::wstring线;
while(std::getline(ifs,line))
结果。推回(标准::移动(线));
返回结果;
}
结构RareWords:boost::static\u访问者{
/////////////////////////////////////
//默认情况下什么也不做
模板void操作符()(T&&)const{/*保持所有其他内容不变*/}
/////////////////////////////////////
//递归数组和对象
void操作符()(JSON::Object&obj)常量{
用于(自动和验证:对象值){
//RareWords::operator()(v.first);/*替换字段名(?)*/
boost::apply_visitor(*这个,v.second);
}
}
void运算符()(JSON::数组和arr)常量{
int i=0;
用于(自动和v:arr.values){
if(i++)//跳过所有数组中的第一个元素
boost::apply_visitor(*这个,v);
}
}
/////////////////////////////////////
//对字符串进行替换
void操作符()(JSON::String&s)常量{
使用名称空间boost;
const static std::vector rareWords=readRareWordList();
常量静态标准::wstring replacement=L“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”;
用于(自动和word:rareWords)
if(word==s.value)
s、 价值=替换;
}
};
int main()
{
autodocument=JSON::readFrom(std::ifstream(“testcases/test3.JSON”);
boost::apply_访问者(RareWords(),文档);

std::cout在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;
}
#包括
#包括“JSON.hpp”
#包括
#包括
#包括
静态std::vector readRareWordList()
{
std::向量结果;
std::wifstream ifs(“testcases/rarewords.txt”);
std::wstring线;
while(std::getline(ifs,line))
结果。推回(标准::移动(线));
返回结果;
}
结构RareWords:boost::static\u访问者{
/////////////////////////////////////
//默认情况下什么也不做
模板void操作符()(T&&)const{/*保持所有其他内容不变*/}
/////////////////////////////////////
//递归数组和对象
void操作符()(JSON::Object&obj)常量{
用于(自动和验证:对象值){
//RareWords::operator()(v.first);/*替换字段名(?)*/
boost::apply_visitor(*这个,v.second);
}
}
void运算符()(JSON::数组和arr)常量{
int i=0;
用于(自动和v:arr.values){
if(i++)//跳过所有数组中的第一个元素
boost::apply_visitor(*这个,v);
}
}
/////////////////////////////////////
//对字符串进行替换
void操作符()(JSON::String&s)常量{
使用名称空间boost;
const static std::vector rareWords=readRareWordList();
常量静态标准::wstring replacement=L“\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu”;
用于(自动和word:rareWords)
if(word==s.value)
s、 价值=替换;
}
};
int main()
{
autodocument=JSON::readFrom(std::ifstream(“testcases/test3.JSON”);
boost::apply_访问者(RareWords(),文档);

std::cout你为什么不做一个
strJSON.replaceAll(“(晚期|填充|罪犯)”,“_ra稀|”
+1当然,我会尝试一下,它可能适用于大多数情况。但问这个问题的主要动机是理解/学习如何操作这样的树。对不起,replaceAll()这对我来说不起作用,因为我的珍品列表有3435长,而且它最终用类似于[“SQ”,“late”]的实例中的“RARE”替换了“SQ”。上述情况的发生是因为在我的珍品列表中有一个“S”。我只是通过查看所有3435个珍品找到了。你为什么不做一个
strJSON.replaceAll((late | populate | cruises),“| u RARE |”)
+1当然,我会尝试一下,它可能适用于大多数情况。但问这个问题的主要动机是理解/学习如何操作这样的树。对不起,replaceAll()对我不起作用,因为我的稀有木材列表有3435长,而且它最终会将[“SQ”,“late”]等实例中的“SQ”替换为“稀有”发生上述情况是因为存在“S”在我的稀薄名单中,我只是通过浏览所有3435个稀薄的词。+ 1的代码,谢谢!因为我不太懂C++。你有可能修改你的代码吗?这样我就可以通过文件传递RealWord了。实际上,我试着缩短我的问题可读性,在我的RealWord表中包含3435个单词,其中一些是COXANIS。mple S.U.S.A.A*与String.replaceAll正则表达式匹配有误。我将在尝试更新代码后接受此答案。是的,从文件中读取单词是非常简单的。但是,我真的需要关于匹配内容的确切示例(你总是想要整个字符串的精确匹配吗?是的,整个字符串的精确匹配。例如:如果“xyz.”在稀有词列表中,则只有“xyz.”应替换为“稀有”而不是“xyz”。如果某个数组类似于[“xyz.”,“xyz.”,则应为[“xyz.”,“稀有”]…请注意,分支数组中的第二个字符串被替换,我们从未接触过第一个字符串。replaceAll方法的另一个缺点是它可能会替换第一个字符串。为了更清晰,我将修改问题以绘制树。如果需要,我可以共享整个输入和稀有文件。@Watt更新为JsonParser parser = new JsonParser(); JsonElement jsonElement = parser.parse(strJSON); JsonArray tree = jsonElement.getAsJsonArray();
#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;
}