Use ICU regular expressions for user-entered regexps
This commit is contained in:
parent
07adb5c84e
commit
8846d77845
2 changed files with 14 additions and 12 deletions
|
@ -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(), ®ex);
|
return a.make_match_state(result.position(), result.position() + result.length(), ®ex);
|
||||||
};
|
};
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue