Джулия, чтобы регулярное выражение соответствовало строкам в файле, таком как grep



Я хотел бы увидеть фрагмент кода julia, который будет читать файл и возвращать строки (строковый тип), соответствующие регулярному выражению.



Я приветствую несколько методов, но результат должен быть эквивалентен следующему:



$> grep -E ^AB[AJ].*TO' 'webster-unabridged-dictionary-1913.txt'

ABACTOR
ABATOR
ABATTOIR
ABJURATORY


я использую GNU grep 3.1 здесь, и первая строка каждой записи в файле-это слово all caps само по себе.

309   3  

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 , которая более удобно выражает анонимную функцию чем синтаксис lamba x -> f(x) для многострочных функций. Это особенно выразительно с командой file open(), определенной с помощью операции 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

    Ничего не найдено.