用于检索带注释字符串

时间:2017-07-13 10:34:36

标签: julia

我有带注释属性的字符串。您可以将它们视为XML文档字符串,但使用自定义注释语法。

字符串中的属性编码如下:

#<atr_name>=<num_of_chars>:<atr_value>\n

,其中

  • <atr_name>是属性的名称
  • <atr_value>是属性
  • 的值
  • <num_of_chars><atr_value>
  • 的字符长度

这是属性名称前缀为#,后缀为=,然后是数字,表示属性值中的字符数,然后是:,然后然后是属性的值本身,然后是换行符\n

以下是一个例子:

julia> string_with_attributes = """
some text
...
#name=6:Azamat
...
#year=4:2016
...
some other text
"""

现在我想编写一个允许我调用的函数或宏:

julia> string_with_attributes["name"]
"Azamat"

julia> string_with_attributes["year"]
"2016"

julia> 

关于如何做到这一点的任何想法?

3 个答案:

答案 0 :(得分:2)

似乎是正则表达式的工作:

julia> string_with_attributes = """
       some text
       dgdfg:dgdf=ert
       #name=6:Azamat
       all34)%(*)#:DG:Ko_=ddhaogj;ldg
       #year=4:2016
       #dkgjdlkdag:dfgdfgd
       some other text
       """
"some text\ndgdfg:dgdf=ert\n#name=6:Azamat\nall34)%(*)#:DG:Ko_=ddhaogj;ldg\n#year=4:2016\n#dkgjdlkdag:dfgdfgd\nsome other text\n"
julia> s = Dict()
Dict{Any,Any} with 0 entries

julia> for i in eachmatch(r"(?<=#)\b.*(?==).*(?=\n)", string_with_attributes)
         push!(s, match(r".*(?==)", i.match).match => match(r"(?<=:).*", i.match).match)
       end

julia> s
Dict{Any,Any} with 2 entries:
  "name" => "Azamat"
  "year" => "2016"

答案 1 :(得分:2)

根据@Gnimuc的回答,如果符合您的需要,您可以创建自己的字符串宏 AKA 非标准字符串文字,例如:

julia> function attr_str(s::S)::Dict{S, S} where {S <: AbstractString}
           d = Dict{S, S}()
           for i in eachmatch(r"(?<=#)\b.*(?==).*(?=\n)", s)
               push!(d, match(r".*(?==)", i.match).match => match(r"(?<=:).*", i.match).match)
           end
           push!(d, "string" => s)
           return d
       end
attr_str (generic function with 1 method)

julia> macro attr_str(s::AbstractString)
           :(attr_str($s))
       end
@attr_str (macro with 1 method)

julia> attr"""
           some text
           dgdfg:dgdf=ert
           #name=6:Azamat
           all34)%(*)#:DG:Ko_=ddhaogj;ldg
           #year=4:2016
           #dkgjdlkdag:dfgdfgd
           some other text
           """
Dict{String,String} with 3 entries:
  "name"   => "Azamat"
  "string" => "some text\ndgdfg:dgdf=ert\n#name=6:Azamat\nall34)%(*)#:DG:Ko_=ddhaogj;ldg\n#year=4:2016\n#dkgjdlkdag:dfgdfgd\nsome other text\n"
  "year"   => "2016"

julia>

答案 2 :(得分:0)

因此,我需要的是从Base.getindex接口扩展Indexing方法。

这是我最终做的解决方案:

julia> 
function Base.getindex(object::S, attribute::AbstractString) where {S <: AbstractString}
    m = match( Regex("#$(attribute)=(\\d*):(.*)\n"), object )
    (typeof(m) == Void) && error("$(object) has no attribute with the name $(attribute)")
    return m.captures[end]::SubString{S}
end


julia> string_with_attributes = """
    some text
    dgdfg:dgdf=ert
    #name=6:Azamat
    all34)%(*)#:DG:Ko_=ddhaogj;ldg
    #year=4:2016
    #dkgjdlkdag:dfgdfgd
    some other text
    """

julia> string_with_attributes["name"]
"Azamat"

julia> string_with_attributes["year"]
"2016"