Соответствие регулярных выражений для не-строк в Ruby без преобразования
Если регулярное выражение Ruby совпадает с чем-то, что не является строкой, to_str
метод вызывается для этого объекта, чтобы получить фактическую строку для сравнения. Я хочу избежать этого поведения; Я хотел бы сопоставить регулярные выражения с объектами, которые не являются строками, но могут логически рассматриваться как произвольно доступные последовательности байтов, и все обращения к ним осуществляются через byte_at()
метод (похож по духу на Java CharSequence.char_at()
метод).
Например, предположим, что я хочу найти смещение байта в произвольном файле произвольного регулярного выражения; выражение может быть многострочным, поэтому я не могу просто читать строку за раз и искать совпадения в каждой строке. Если файл очень большой, я не могу поместить все это в память, поэтому я не могу просто прочитать его как одну большую строку. Однако было бы достаточно просто определить метод, который получает n-й байт файла (с буферизацией и кэшированием по мере необходимости для скорости).
В конце концов, мне бы хотелось создать полнофункциональный класс веревочки, как в Ruby Quiz # 137, и я хотел бы иметь возможность использовать регулярные выражения на них без потери производительности при преобразовании их в строки.
Я не хочу встать на ноги во внутренностях реализации регулярных выражений Ruby, поэтому любая оценка будет оценена.
1 ответ
Ты не можешь Это не поддерживалось в Ruby 1.8.х, вероятно, потому что это такой крайний случай; а в 1.9 это даже не имеет смысла. Ruby 1.9 не отображает свои строки в байты каким-либо образом, обслуживаемым пользователем; вместо этого он использует символьные кодовые точки, чтобы он мог поддерживать множество кодировок, которые он принимает. И новый оптимизированный движок регулярных выражений 1.9, Oniguruma, также основан на той же концепции кодирования и кодовых точек. Байты просто не входят в картинку на этом уровне.
У меня есть подозрение, что вы просите о преждевременной оптимизации. Для любого разумного объекта Ruby реализация to_str не должна быть огромным препятствием для производительности. Если это так, то Ruby, вероятно, не тот инструмент, который вам подходит, поскольку он абстрагирует и изолирует вас от ваших необработанных данных различными способами.
Ваш пример поиска последовательности байтов в большом двоичном файле не идеальный вариант использования для Ruby - вам лучше использовать grep или какой-либо другой инструмент Unix. Если вам нужны результаты в вашей Ruby-программе, запустите ее как системный процесс, используя обратные пометки, и обработайте вывод.