Java 如何操作JSON树的叶子
我想使用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",
\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;
}