#prog #rust #article
symbolic derivatives and the rust rewrite of RE#Растовая версия очень быстрого движка для регулярных выражений, который поддерживает, помимо прочего, конъюкцию (пересечение результатов подвыражений), отрицание и lookahead и при этом работает за линейное от входных данных время. По производительности на выражениях с большим количеством состояний обгоняет
regex, особенно для поиска без учёта регистра.
Теория, поддерживающая этот движок — это развитие
идей Brzozowski, но вместо того, чтобы считать производную от регулярного выражения для разных символов и потом объединять их по классам эквивалентности, новый подход считает т. н. символическую производную — производную для всех возможных входных символов сразу.
Из-за того, что данный подход поддерживает конъюкцию, движок может работать на байтах и при этом поддерживать UTF-8 просто за счёт добавления правила, которое ограничивает вход до валидных UTF-8 последовательностей:
// \p{utf8} expands to:
// ([\x00-\x7F]
// | [\xC0-\xDF][\x80-\xBF]
// | [\xE0-\xEF][\x80-\xBF]{2}
// | [\xF0-\xF7][\x80-\xBF]{3})*Пример кода:
use resharp::Regex;
// basic matching
let re = Regex::new(r"hello.*world").unwrap();
assert!(re.is_match("hello beautiful world"));
// intersection: contains both "cat" and "dog", 5-15 chars
let re = Regex::new(r"_*cat_*&_*dog_*&_{5,15}").unwrap();
// complement: does not contain "1"
let re = Regex::new(r"~(_*1_*)").unwrap();