julia 正则表达式匹配文件中的行,例如 grep

Mer*_*lin 5 julia

我想看到 Julia 的代码片段,它将读取文件并返回与正则表达式匹配的行(字符串类型)。

我欢迎多种技术,但输出应相当于以下内容:

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

ABACTOR
ABATOR
ABATTOIR
ABJURATORY
Run Code Online (Sandbox Code Playgroud)

我在这里使用 GNU grep 3.1,文件中每个条目的第一行都是大写单词。

Mer*_*lin 5

我最喜欢的解决方案使用简单的循环并且非常容易理解。

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
Run Code Online (Sandbox Code Playgroud)

笔记

  • 带有制表符分隔的行会保留制表符(没有“\t”的文字输出)
  • 在这个例子中,我的源文件在定义上方的一行中仅包含全部大写的字典单词;返回完整的行。
  • 文件 I/O 操作被包装在do 块语法结构x -> f(x)中,对于多行函数来说,它比 lba 语法更方便地表达匿名函数。这对于 file 命令来说尤其具有表现力,当使用函数作为参数调用时,该命令open()是通过操作定义的。try-finally-close
  • Julia 文档:字符串/正则表达式
    • 正则表达式对象采用以下形式r"<regex_literal_here>"
    • 正则表达式本身是一个字符串
    • 基于perl PCRE库
    • 匹配成为正则表达式匹配对象

例子

julia> reg = r"^AB[AJ].*TO";
julia> typeof(reg)
Regex

julia> test = match(reg, "ABJURATORY")
RegexMatch("ABJURATO")

julia> typeof(test)
RegexMatch
Run Code Online (Sandbox Code Playgroud)

  • `ismatch()` 在 Julia &gt; 1.0 中已弃用。相反,应该使用“occurrin()”。 (2认同)

Ian*_*all 5

您还可以使用该filter函数在一行中完成此操作。

filter(line -> ismatch(r"^AB[AJ].*TO",line),readlines(open("webster-unabridged-dictionary-1913.txt")))
Run Code Online (Sandbox Code Playgroud)

filter将返回布尔值的函数应用于数组,并且仅返回数组中的那些元素true。本例中的函数是一个匿名函数line -> ismatch(r"^AB[AJ].*TO",line)",它基本上表示调用被过滤的数组的每个元素(在本例中为每一行)line

我认为这对于非常大的文件可能不是最好的解决方案,因为整个文件需要在过滤之前加载到内存中,但对于这个例子来说,它似乎与使用eachline. 另一个区别是,此解决方案将结果作为数组返回,而不是打印每个结果,这取决于您想要对匹配项执行的操作可能是好事还是坏事。