Джулия, чтобы регулярное выражение соответствовало строкам в файле, таком как grep
Я хотел бы увидеть фрагмент кода julia, который будет читать файл и возвращать строки (строковый тип), соответствующие регулярному выражению.
Я приветствую несколько методов, но результат должен быть эквивалентен следующему:
$> grep -E ^AB[AJ].*TO' 'webster-unabridged-dictionary-1913.txt'
ABACTOR
ABATOR
ABATTOIR
ABJURATORY
я использую GNU grep 3.1 здесь, и первая строка каждой записи в файле-это слово all caps само по себе.
3 ответов:
Мое любимое решение использует простой цикл и очень легко понять.
julia> open("webster-unabridged-dictionary-1913.txt") do f for i in eachline(f) if ismatch(r"^AB[AJ].*TO", i) println(i) end end end ABACTOR ABATOR ABATTOIR ABJURATORYПримечания
- строки с разделением табуляции имеют сохраненные табуляции (без буквального вывода '\t')
- мой исходный файл в этом примере содержит словарные слова во всех заглавных буквах только на одну строку выше определения; возвращается полная строка.
Операция ввода-вывода файла обернута в синтаксическую структуру do block , которая более удобно выражает анонимную функцию чем синтаксис lambax -> f(x)для многострочных функций. Это особенно выразительно с командой fileopen(), определенной с помощью операцииtry-finally-closeпри вызове функции в качестве аргумента.- Julia docs: Strings / Regular Expressions
- объекты регулярных выражений принимают вид
r"<regex_literal_here>"- само регулярное выражение является строкой
- на основе perl PCRE library
- совпадения становятся объектами регулярных выражений
Пример
julia> reg = r"^AB[AJ].*TO"; julia> typeof(reg) Regex julia> test = match(reg, "ABJURATORY") RegexMatch("ABJURATO") julia> typeof(test) RegexMatch
Вы также можете использовать функцию
filter, чтобы сделать это в одной строке.filter(line -> ismatch(r"^AB[AJ].*TO",line),readlines(open("webster-unabridged-dictionary-1913.txt")))
filterприменяет функцию, возвращающую логическое значение к массиву, и возвращает только те элементы массива, которые являютсяtrue. Функция в этом случае является анонимной функциейline -> ismatch(r"^AB[AJ].*TO",line)", которая в основном говорит о вызове каждого элемента фильтруемого массива (в данном случае каждой строки)line.Я думаю, что это не лучшее решение для очень больших файлов, так как весь файл должен быть загружен в память. перед фильтрацией, но для этого примера он кажется таким же быстрым, как и цикл for с использованием
eachline. Другое отличие заключается в том, что это решение возвращает результаты в виде массива, а не печатает каждый из них, что в зависимости от того, что вы хотите сделать с совпадениями, может быть хорошим или плохим.
Просто положить
;впереди-это способ Джулии использовать команды командной строки, поэтому это работает в REPL Джулии;grep -E ^AB[AJ].*TO' 'webster-unabridged-dictionary-1913.txt'
Comments