I want to replace rare words with _RARE_
in a JSON tree using JAVA.
My rareWords list contains
late
populate
convicts
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