2

文字列があるとします

local a = "Hello universe"

部分文字列「宇宙」を見つける

a:find("universe")

さて、文字列が

local a = "un#verse"

検索する文字列はユニバースです。ただし、部分文字列は 1 文字異なります。したがって、明らかにLuaはそれを無視します。

一文字違いでも文字列を検索させるにはどうすればよいですか?

4

4 に答える 4

5

文字がどこにあるかがわかっている場合は、.その文字の代わりに使用します。a:find("un.verse")

ただし、あいまい文字列検索を探しているようです。Luastringライブラリの範囲外です。この記事から始めることをお勧めします:http://ntz-develop.blogspot.com/2011/03/fuzzy-string-search.html

Luaあいまい検索の実装について—私は何も使用していませんが、「luaあいまい検索」をグーグルで検索するといくつかの結果が得られます。いくつかはこの論文に基づいています:http://web.archive.org/web/20070518080535/http ://www.heise.de/ct/english/97/04/386/

https://github.com/ajsher/luafuzzyを試してください。

于 2012-10-19T07:03:15.473 に答える
4

TREの行に沿って何かが必要なようです:

TRE は、軽量で堅牢、かつ効率的な POSIX 準拠の正規表現マッチング ライブラリであり、近似 (ファジー) マッチングなどの優れた機能を備えています。

近似パターン マッチングを使用すると、一致を近似することができます。つまり、ある程度の近さで一致を検索パターンに近づけることができます。TRE は編集距離尺度 (レーベンシュタイン距離とも呼ばれます) を使用します。この距離では、検索されたテキストで文字を挿入、削除、または置換して、完全に一致させることができます。挿入、削除、または置換ごとに、一致の距離またはコストが追加されます。TRE は、特定のしきい値よりもコストが低い一致を報告できます。TRE を使用して、コストが最も低い一致を検索することもできます。

そのための Lua バインディングはlrexlibの一部として利用できます。

于 2012-10-19T08:30:47.413 に答える
2

独自の単純なロール アプローチ (パターンが同じ長さを維持するという仮定に基づく):

function hammingdistance(a,b)
    local ta={a:byte(1,-1)}
    local tb={b:byte(1,-1)}
    local res = 0
    for k=1,#a do
        if ta[k]~=tb[k] then
            res=res+1
        end
    end
    print(a,b,res) -- debugging/demonstration print
    return res
end

function fuz(s,pat)
    local best_match=10000
    local best_location
    for k=1,#s-#pat+1 do
        local cur_diff=hammingdistance(s:sub(k,k+#pat-1),pat)
        if  cur_diff < best_match then
            best_location = k
            best_match = cur_diff
        end
    end
    local start,ending = math.max(1,best_location),math.min(best_location+#pat-1,#s)
    return start,ending,s:sub(start,ending)
end

s=[[Hello, Universe! UnIvErSe]]
print(fuz(s,'universe'))

免責事項:お勧めしません。楽しみのためだけです:

より良い構文が必要な場合 (標準型のメタテーブルをいじっても構わない場合) は、次のように使用できます。

getmetatable('').__sub=hammingdistance
a='Hello'
b='hello'
print(a-b)

ただし、この方法でa-bは等しくないことに注意してください。b-a

于 2012-10-19T09:43:53.257 に答える
2

単一の文字の違いを本当に探していて、パフォーマンスを気にしない場合は、次の簡単な方法を使用できます。

local a = "Hello un#verse"

local myfind = function(s,p)  
  local withdot = function(n)
    return p:sub(1,n-1) .. '.' .. p:sub(n+1)
  end
  local a,b
  for i=1,#s do
    a,b = s:find(withdot(i))
    if a then return a,b end
  end
end

print(myfind(a,"universe"))
于 2012-10-19T09:59:31.773 に答える