Я бы определил функцию следующим образом:
(defn parse-text-cms [sel-row]
(with-open [input (clojure.java.io/reader "cms/tb_cms.txt")]
(first
(for [[_ number line] (map (partial re-find #"@@(\d)+\s+(.*)")
(line-seq input))
:when (= number (str sel-row))]
line))))
Сочетание line-seq
и reader
дает мне последовательность строк из входного файла.with-open
гарантирует, что файл будет правильно закрыт, когда я закончу.Я применяю регулярное выражение к каждой строке, которая ищет @@
, за которой следуют число и несколько пробелов.
re-find
возвращает вектор с тремя элементами:
- вся совпадающая строка
- номер (первая группа в регулярном выражении)
- остальная часть строки (вторая группа в регулярном выражении)
Я связываю их с number
и line
, используя деструктуризацию в выражении for
(меня не интересуетвся согласованная линия, поэтому я игнорирую это).Я фильтрую для выбранного sel-row
, используя :when
, и получаю только (остальные) line
.
Поскольку я ожидаю только одно совпадение в файле, я возвращаю только первый элемент из последовательностипостроено for
.Из-за лени for
, map
и line-seq
это также останавливает чтение файла после того, как элемент найден.
Если вы выполняете много операций поиска строк, я бы предложил загрузитьвесь файл в память вместо того, чтобы читать его каждый раз.