Use ICU regular expressions for user-entered regexps

This commit is contained in:
Thomas Goyne 2013-01-28 20:36:54 -08:00
parent 07adb5c84e
commit 8846d77845
2 changed files with 14 additions and 12 deletions

View file

@ -57,7 +57,7 @@ public:
return (d->*field).get().substr(s); return (d->*field).get().substr(s);
} }
MatchState make_match_state(size_t s, size_t e, boost::regex *r = nullptr) { MatchState make_match_state(size_t s, size_t e, boost::u32regex *r = nullptr) {
return MatchState(s + start, e + start, r); return MatchState(s + start, e + start, r);
} }
}; };
@ -107,7 +107,7 @@ public:
return out; return out;
} }
MatchState make_match_state(size_t s, size_t e, boost::regex *r = nullptr) { MatchState make_match_state(size_t s, size_t e, boost::u32regex *r = nullptr) {
s += start; s += start;
e += start; e += start;
@ -141,16 +141,16 @@ public:
template<typename Accessor> template<typename Accessor>
matcher get_matcher(SearchReplaceSettings const& settings, Accessor&& a) { matcher get_matcher(SearchReplaceSettings const& settings, Accessor&& a) {
if (settings.use_regex) { if (settings.use_regex) {
int flags = boost::regex::perl; int flags = boost::u32regex::perl;
if (!settings.match_case) if (!settings.match_case)
flags |= boost::regex::icase; flags |= boost::u32regex::icase;
boost::regex regex(settings.find, flags); auto regex = boost::make_u32regex(settings.find, flags);
return [=](const AssDialogue *diag, size_t start) mutable -> MatchState { return [=](const AssDialogue *diag, size_t start) mutable -> MatchState {
boost::smatch result; boost::smatch result;
auto const& str = a.get(diag, start); auto const& str = a.get(diag, start);
if (!regex_search(str, result, regex, start > 0 ? boost::match_not_bol : boost::match_default)) if (!u32regex_search(str, result, regex, start > 0 ? boost::match_not_bol : boost::match_default))
return MatchState(); return MatchState();
return a.make_match_state(result.position(), result.position() + result.length(), &regex); return a.make_match_state(result.position(), result.position() + result.length(), &regex);
}; };
@ -207,7 +207,7 @@ void SearchReplaceEngine::Replace(AssDialogue *diag, MatchState &ms) {
std::string replacement = settings.replace_with; std::string replacement = settings.replace_with;
if (ms.re) { if (ms.re) {
auto to_replace = text.substr(ms.start, ms.end - ms.start); auto to_replace = text.substr(ms.start, ms.end - ms.start);
replacement = regex_replace(to_replace, *ms.re, replacement, boost::format_first_only); replacement = u32regex_replace(to_replace, *ms.re, replacement, boost::format_first_only);
} }
diag_field = text.substr(0, ms.start) + replacement + text.substr(ms.end); diag_field = text.substr(0, ms.start) + replacement + text.substr(ms.end);
@ -309,8 +309,10 @@ bool SearchReplaceEngine::ReplaceAll() {
if (MatchState ms = matches(diag, 0)) { if (MatchState ms = matches(diag, 0)) {
auto& diag_field = diag->*get_dialogue_field(settings.field); auto& diag_field = diag->*get_dialogue_field(settings.field);
std::string const& text = diag_field.get(); std::string const& text = diag_field.get();
count += distance(boost::sregex_iterator(begin(text), end(text), *ms.re), boost::sregex_iterator()); count += distance(
diag_field = regex_replace(text, *ms.re, settings.replace_with); boost::u32regex_iterator<std::string::const_iterator>(begin(text), end(text), *ms.re),
boost::u32regex_iterator<std::string::const_iterator>());
diag_field = u32regex_replace(text, *ms.re, settings.replace_with);
} }
continue; continue;
} }

View file

@ -15,18 +15,18 @@
// Aegisub Project http://www.aegisub.org/ // Aegisub Project http://www.aegisub.org/
#include <functional> #include <functional>
#include <boost/regex.hpp> #include <boost/regex/icu.hpp>
#include <string> #include <string>
namespace agi { struct Context; } namespace agi { struct Context; }
class AssDialogue; class AssDialogue;
struct MatchState { struct MatchState {
boost::regex *re; boost::u32regex *re;
size_t start, end; size_t start, end;
MatchState() : re(nullptr), start(0), end(-1) { } MatchState() : re(nullptr), start(0), end(-1) { }
MatchState(size_t s, size_t e, boost::regex *re) : re(re), start(s), end(e) { } MatchState(size_t s, size_t e, boost::u32regex *re) : re(re), start(s), end(e) { }
operator bool() const { return end != (size_t)-1; } operator bool() const { return end != (size_t)-1; }
}; };