2014-04-13 12:21:30 +02:00
|
|
|
#include "concordia/sentence_anonymizer.hpp"
|
|
|
|
|
2014-04-29 14:46:04 +02:00
|
|
|
#include "concordia/common/text_utils.hpp"
|
|
|
|
#include <boost/foreach.hpp>
|
|
|
|
#include <fstream>
|
|
|
|
#include <sstream>
|
|
|
|
#include <iostream>
|
|
|
|
#include <boost/algorithm/string.hpp>
|
|
|
|
|
|
|
|
SentenceAnonymizer::SentenceAnonymizer(
|
|
|
|
boost::shared_ptr<ConcordiaConfig> config)
|
2014-04-13 12:21:30 +02:00
|
|
|
throw(ConcordiaException) {
|
2014-04-29 14:46:04 +02:00
|
|
|
_createNeRules(config->getNamedEntitiesFilePath());
|
|
|
|
_createHtmlTagsRule(config->getHtmlTagsFilePath());
|
|
|
|
_stopWords = _getMultipleReplacementRule(
|
|
|
|
config->getStopWordsFilePath(), "", true);
|
|
|
|
_stopSymbols = _getMultipleReplacementRule(
|
|
|
|
config->getStopSymbolsFilePath(), "");
|
|
|
|
_spaceSymbols = _getMultipleReplacementRule(
|
|
|
|
config->getSpaceSymbolsFilePath(), " ");
|
2014-04-13 12:21:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
SentenceAnonymizer::~SentenceAnonymizer() {
|
|
|
|
}
|
|
|
|
|
2015-04-15 14:14:10 +02:00
|
|
|
std::string SentenceAnonymizer::anonymize(const std::string & sentence) {
|
|
|
|
std::string result = sentence;
|
2014-04-29 14:46:04 +02:00
|
|
|
|
|
|
|
result = _htmlTags->apply(result);
|
|
|
|
|
|
|
|
BOOST_FOREACH(RegexReplacement & neRule, _namedEntities) {
|
|
|
|
result = neRule.apply(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
result = TextUtils::getInstance().toLowerCase(result);
|
|
|
|
|
|
|
|
result = _stopWords->apply(result);
|
|
|
|
result = _stopSymbols->apply(result);
|
|
|
|
result = _spaceSymbols->apply(result);
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2015-04-15 14:14:10 +02:00
|
|
|
void SentenceAnonymizer::_createNeRules(std::string & namedEntitiesPath) {
|
2014-04-29 14:46:04 +02:00
|
|
|
if (boost::filesystem::exists(namedEntitiesPath)) {
|
2015-04-15 14:14:10 +02:00
|
|
|
std::string line;
|
|
|
|
std::ifstream neFile(namedEntitiesPath.c_str());
|
2014-04-29 14:46:04 +02:00
|
|
|
if (neFile.is_open()) {
|
|
|
|
int lineCounter = 0;
|
|
|
|
while (getline(neFile, line)) {
|
|
|
|
lineCounter++;
|
2015-04-15 14:14:10 +02:00
|
|
|
boost::shared_ptr<std::vector<std::string> >
|
|
|
|
tokenTexts(new std::vector<std::string>());
|
2014-04-29 14:46:04 +02:00
|
|
|
boost::split(*tokenTexts, line, boost::is_any_of(" "),
|
|
|
|
boost::token_compress_on);
|
|
|
|
if (tokenTexts->size() != 2) {
|
2015-04-15 14:14:10 +02:00
|
|
|
std::stringstream ss;
|
2014-04-29 14:46:04 +02:00
|
|
|
ss << "Invalid line: " << lineCounter
|
|
|
|
<< " in NE file: " << namedEntitiesPath;
|
|
|
|
throw ConcordiaException(ss.str());
|
|
|
|
} else {
|
2015-04-15 10:55:26 +02:00
|
|
|
_namedEntities.push_back(RegexReplacement(
|
2014-04-29 14:46:04 +02:00
|
|
|
tokenTexts->at(0), tokenTexts->at(1)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
neFile.close();
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("Unable to read named entities file.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("No named entities file.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-15 14:14:10 +02:00
|
|
|
void SentenceAnonymizer::_createHtmlTagsRule(std::string & htmlTagsPath) {
|
|
|
|
std::string tagsExpression = "<\\/?(";
|
2014-04-29 14:46:04 +02:00
|
|
|
if (boost::filesystem::exists(htmlTagsPath)) {
|
2015-04-15 14:14:10 +02:00
|
|
|
std::string line;
|
|
|
|
std::ifstream tagsFile(htmlTagsPath.c_str());
|
2014-04-29 14:46:04 +02:00
|
|
|
if (tagsFile.is_open()) {
|
|
|
|
while (getline(tagsFile, line)) {
|
|
|
|
tagsExpression += "|";
|
|
|
|
}
|
|
|
|
tagsFile.close();
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("Unable to read html tags file.");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("No html tags file.");
|
|
|
|
}
|
|
|
|
tagsExpression = tagsExpression.substr(0, tagsExpression.size()-1);
|
|
|
|
tagsExpression += "br).*?>";
|
|
|
|
_htmlTags = boost::shared_ptr<RegexReplacement>(
|
|
|
|
new RegexReplacement(tagsExpression, "", false));
|
|
|
|
}
|
2014-04-13 12:21:30 +02:00
|
|
|
|
2014-04-29 14:46:04 +02:00
|
|
|
boost::shared_ptr<RegexReplacement>
|
2015-04-15 14:14:10 +02:00
|
|
|
SentenceAnonymizer::_getMultipleReplacementRule(
|
|
|
|
std::string & filePath, std::string replacement, bool wholeWord) {
|
|
|
|
std::string expression = "(";
|
2014-04-29 14:46:04 +02:00
|
|
|
if (boost::filesystem::exists(filePath)) {
|
2015-04-15 14:14:10 +02:00
|
|
|
std::string line;
|
|
|
|
std::ifstream ruleFile(filePath.c_str());
|
2014-04-29 14:46:04 +02:00
|
|
|
if (ruleFile.is_open()) {
|
|
|
|
while (getline(ruleFile, line)) {
|
|
|
|
if (wholeWord) {
|
|
|
|
expression += "\\b";
|
|
|
|
}
|
|
|
|
expression += line;
|
|
|
|
if (wholeWord) {
|
|
|
|
expression += "\\b";
|
|
|
|
}
|
|
|
|
expression += "|";
|
|
|
|
}
|
|
|
|
ruleFile.close();
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("Unable to read file: "+filePath);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
throw ConcordiaException("No "+filePath+" file.");
|
|
|
|
}
|
|
|
|
expression = expression.substr(0, expression.size()-1);
|
|
|
|
expression += ")";
|
|
|
|
return boost::shared_ptr<RegexReplacement>(
|
|
|
|
new RegexReplacement(expression, replacement, false));
|
2014-04-13 12:21:30 +02:00
|
|
|
}
|
|
|
|
|