Lua:明确检查nil后字符串为nil

Posted

技术标签:

【中文标题】Lua:明确检查nil后字符串为nil【英文标题】:Lua: String is nil after explicitly checking for nil 【发布时间】:2015-09-30 12:07:56 【问题描述】:

我已经编写了一个脚本来从数据库中获取患者数据。

它适用于前几百名患者,但在某个随机点我得到了错误:

*** lua 运行错误 BatchDicomMove.lua:91: 尝试将 nil 与 'dofile('BatchDicomMove.lua')' 中的字符串进行比较

尽管我明确检查了参数是否为零。 此外,当我对代码进行更改时(比如添加一个空行)。错误只是发生在另一个地方。被访问。

可能出了什么问题?

-- execute this script by calling: dgate "--lua:dofile('BatchDicomMove.lua')"

-- MOP: Query=STUDY|SERIES Move=STUDY+StudyInstanceUID
-- GEPACS_RSD: Query=* Move=SERIES

inputFile       = 'PatientList.txt'
srcAet          = 'NUKALFA'
destAet         = 'ONCO_PACS_RD'
modalities      = 'CT','PT'
includeStr      = 'Standard','standard','AC'  -- if non are desired enter 
includeOrAnd    = 'or'                          -- choose 'and', 'or'
excludeStr      = 'NAC','CTAC'                -- if non are desired enter 
excludeOrAnd    = 'nor'                         -- choose 'neither', 'nor'
select          = 'newest'                      -- choose 'newest', 'oldest', 'all'
relativeToTime  = 'before'                      -- choose 'before', 'after', 'exact'




for line in io.lines(inputFile) do
    -- Loop through all patients

    date = ''
    date1 = ''
    date2 = ''
    stringSplit = string.find(line,' ')
    if stringSplit == nil then
        ptId = line
    else
        ptId = string.sub(line,0,stringSplit-1)
        date = string.sub(line,stringSplit+1)
        if string.len(date) == 18 then
            stringSplit = string.find(date,' ')
            if stringSplit == nil then
                date = ''
            else
                date = ''
                date1 = string.sub(date,0,stringSplit-1)
                date2 = string.sub(line,stringSplit+1)
            end
        elseif string.len(date) ~= 9 then
            date = ''
        end
    end
    -- ptIdAlts ensures that the patient will be found nomater if '-' is included in the ID or not
    stringSplit = string.find(ptId,'-')
    if stringSplit == nil then
        ptId = string.sub(ptId,0,7) .. '-' .. string.sub(ptId,8)
    end
    stringSplit = string.find(ptId,'-')
    ptIdAlts = ptId,string.sub(ptId,0,stringSplit-1) .. string.sub(ptId,stringSplit+1)

    print('  Query: patient', ptIdAlts[1], 'from', srcAet, 'to', destAet)

    -- an extra loop have been added as part of implementation of ptIdAlts
    b = 
    for key, ptId in ipairs(ptIdAlts) do
        for key, modality in ipairs(modalities) do

            -- create query for dicom move
            q = newdicomobject()
            q.PatientID = ptId
            q.Modality = modality
            -- values to retrive should be included in the query
            q.StudyInstanceUID  = ''
            q.SeriesInstanceUID = ''
            q.PatientName = ''
            q.SeriesDescription = ''
            q.StudyDate = ''

            -- execute query for infomation on patient data on the source machine
            a = dicomquery(srcAet, 'SERIES', q) -- sets QueryRetrieveLevel at call time
            for i=1,#a do 
                b[#b+1] = a[i-1] 
            end
        end
    end

    -- Remove unwanted resultes

    c = 
    if date ~= '' then
        for i, a in ipairs(b) do
            if a.StudyDate ~= nil then
                if relativeToTime == 'exact' then
                    if a.StudyDate == date then
                        c[#c+1] = a
                    end
                elseif relativeToTime == 'before' then
                    if a.StudyDate <= date then
                        c[#c+1] = a
                    end
                else
                    if a.StudyDate >= date then
                        c[#c+1] = a
                    end
                end
            end
        end
    elseif (date1 ~= '') and (date2 ~= '') then
        for i, a in ipairs(b) do
            if (a.StudyDate ~= nil) and (a.StudyDate >= date1) and (a.StudyDate <= date2) then
                c[#c+1] = a
            end
        end
    else
        c = b
    end
    b = c

    c = 
    if #includeStr ~= 0 then
        for key, a in ipairs(b) do
            if a.SeriesDescription ~= nil then
                if includeOrAnd == 'or' then
                    for key, include in ipairs(includeStr) do
                        if string.match(a.SeriesDescription,include) ~= nil then
                            c[#c+1] = a
                            break
                        end
                    end
                else
                    for key, include in ipairs(includeStr) do
                        if string.match(a.SeriesDescription,include) == nil then
                            break
                        end
                        c[#c+1] = a
                    end
                end
            end
        end
        b = c
    end

    c = 
    if #excludeStr ~= 0 then
        for key, a in ipairs(b) do
            if a.SeriesDescription ~= nil then
                if excludeOrAnd == 'nor' then
                    for key, exclude in ipairs(excludeStr) do
                        if string.match(a.SeriesDescription,exclude) ~= nil then
                            break
                        end
                        c[#c+1] = a
                    end
                else
                    for key, exclude in ipairs(excludeStr) do
                        if string.match(a.SeriesDescription,exclude) == nil then
                            c[#c+1] = a
                            break
                        end
                    end
                end
            end
        end
        b = c
    end

    c = 
    if select == 'newest' then
        for key, modality in ipairs(modalities) do
            for i, a in ipairs(b) do
                if a.StudyDate ~= nil then
                    if c[key] == nil then
                        c[key] = a
                    elseif c[key].StudyDate < a.StudyDate then
                        c[key] = a
                    end
                end
            end
        end
    elseif select == 'oldest' then
        for key, modality in ipairs(modalities) do
            for i, a in ipairs(b) do
                if a.StudyDate ~= nil then
                    if c[key] == nil then
                        c[key] = a
                    elseif c[key].StudyDate > a.StudyDate then
                        c[key] = a
                    end
                end
            end
        end
    else
        c = b
    end
    b = c

    n = #b
    print('  Query results:', n)

    for key, a in ipairs(b) do
        cmd = newdicomobject()
        cmd.PatientID = b.PatientID
        cmd.StudyInstanceUID = b.StudyInstanceUID
        cmd.SeriesInstanceUID = b.SeriesInstanceUID

        if srcAet == 'MOP_SCP' then
            cmd.QueryRetrieveLevel = 'STUDY' -- only level supported by the MOP for dicom move
            cmd.Modality = b.Modality
        else
            cmd.QueryRetrieveLevel = 'SERIES' -- tested on GEPACS_RSD
        end

        -- execute the move
        --dicommove(srcAet, destAet, cmd);
    end
end
print('  Done.')

【问题讨论】:

sn-p 中的第 91 行到底是哪一行?它在哪一行输入失败?该错误来自relational operators,而不是==~=,因此请检查您是否有保护它们。 【参考方案1】:

这个文件第90行和第94行有比较:

line 90: if a.StudyDate <= date then
line 94: if a.StudyDate >= date then

我们可以看到 a.StudyDate 不是 nil,因为您在第 84 行检查了它。 因此,我的猜测是 date 可能为零。

另一个地方在第 102 行:

if (a.StudyDate ~= nil) and (a.StudyDate >= date1) and (a.StudyDate <= date2)

再次检查 date1date2 是否不为零。

同样,您可能应该检查 'c[key].StudyDate' 第 178 行。

【讨论】:

我也发布了一个答案,但是把行号弄错了,所以认为最好删除。但是,我注意到的重要一点是代码仅检查 date ~= '' 而不是 date ~= nil 感谢您的建议,但 date、date1 和 date2 从未被报告为 nil。总是 a. 部分变为 nil。我可以在发生错误之前将值打印到屏幕上,并且值不为零。

以上是关于Lua:明确检查nil后字符串为nil的主要内容,如果未能解决你的问题,请参考以下文章

lua: function_demo.lua:144: bad argument #2 to 'find' (string expected, got nil

Lua函数返回字符串,但调用函数得到nil

Lua 数据类型

Swift - 将 nil 核心数据字符串转换为可选值

有没有办法将 lua 函数从 C++ 更改为 nil,例如 changefunction(thefunction) 并且在调用时变为 nil

在 Lua 中将表及其子表设置为 nil 有啥区别?